diff --git a/.changeset/defer-until-thread.md b/.changeset/defer-until-thread.md new file mode 100644 index 00000000..84944405 --- /dev/null +++ b/.changeset/defer-until-thread.md @@ -0,0 +1,5 @@ +--- +"@plotday/twister": minor +--- + +Added: `NewNote.deferUntilThread` holds a note addressed by `{ source }` until a thread with that source exists, instead of returning `null` when it has not synced yet. diff --git a/twister/src/plot.ts b/twister/src/plot.ts index 4c4d4b92..0b9d6b09 100644 --- a/twister/src/plot.ts +++ b/twister/src/plot.ts @@ -869,6 +869,35 @@ export type NewNote = Partial< */ authoredBySelf?: boolean; + /** + * Keep this note until its thread exists, instead of dropping it. + * + * A note addressed by `{ source }` normally resolves immediately, and + * `saveNote` returns `null` when no thread carries that source — which for + * a connector usually means the item this note belongs to has not synced + * yet. Set this to have the platform hold the note and attach it as soon + * as a thread with that source appears, rather than making you store and + * retry it yourself. + * + * Recommended for any `{ source }`-addressed note whose target is synced + * by a different product or connector and may therefore lag. Leave it + * unset when a miss means the note is genuinely undeliverable: `null` is + * then the signal you want, and holding the note would accumulate payloads + * for a thread that will never arrive. + * + * Held notes are dropped after a bounded retry window. Ordering is not + * guaranteed relative to notes that attached immediately, so set `created` + * (as connectors already should) rather than relying on arrival order. + * + * At most one UNKEYED held note survives per `{ source }`: two deferred + * notes without a `key` addressed to the same still-unresolved source + * collapse onto a single held slot, and the second one you save silently + * replaces the first — it does not queue as a second note. If you may + * defer more than one note to the same unresolved source, give each a + * distinct `key` so they are held separately. + */ + deferUntilThread?: boolean; + /** * Format of the note content. Determines how the note is processed: * - 'text': Plain text that will be converted to markdown (auto-links URLs, preserves line breaks)