@typecaast/core 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,18 +7,8 @@ import { ContentNode } from '@typecaast/schema';
7
7
  type ResolvedTheme = "light" | "dark";
8
8
  /** Lifecycle state of a rendered thread item. */
9
9
  type MessageState = "typing" | "sending" | "sent" | "edited" | "deleted";
10
- /** Whether a thread item is a regular message or an app/system card. */
10
+ /** Whether a thread item is a regular message or a system/notice line. */
11
11
  type MessageVariant = "message" | "system";
12
- /** A system/app card payload (e.g. "Pull request opened" + action buttons). */
13
- interface SystemCard {
14
- /** Named card variant the skin renders, e.g. `"pr-opened"`. */
15
- card?: string;
16
- actions?: {
17
- label: string;
18
- href?: string;
19
- variant?: "primary" | "secondary";
20
- }[];
21
- }
22
12
  /** A reaction currently shown on a message. */
23
13
  interface RenderedReaction {
24
14
  emoji: string;
@@ -54,8 +44,6 @@ interface RenderedMessage {
54
44
  isGrouped: boolean;
55
45
  /** Display time in ms from timeline start. */
56
46
  atMs: number;
57
- /** Present when `variant === "system"`. */
58
- system?: SystemCard;
59
47
  }
60
48
  /** A typing indicator currently shown. */
61
49
  interface TypingState {
@@ -209,4 +197,4 @@ declare class TimelinePlayer implements Player {
209
197
  /** Create a real-time player over a `GetStateAt`. */
210
198
  declare function createPlayer(getStateAt: GetStateAt, options: PlayerOptions): Player;
211
199
 
212
- export { type ComposerState as C, type GetStateAt as G, type MessageVariant as M, type Player as P, type ResolvedTheme as R, type SystemCard as S, type TypingState as T, type RenderedMessage as a, type RenderedReaction as b, type SimState as c, type MessageState as d, type PlayerEvent as e, type PlayerEventMap as f, type PlayerOptions as g, type ScrollReason as h, type ScrollState as i, TimelinePlayer as j, createPlayer as k };
200
+ export { type ComposerState as C, type GetStateAt as G, type MessageVariant as M, type Player as P, type ResolvedTheme as R, type SimState as S, type TypingState as T, type RenderedMessage as a, type RenderedReaction as b, type MessageState as c, type PlayerEvent as d, type PlayerEventMap as e, type PlayerOptions as f, type ScrollReason as g, type ScrollState as h, TimelinePlayer as i, createPlayer as j };
@@ -7,18 +7,8 @@ import { ContentNode } from '@typecaast/schema';
7
7
  type ResolvedTheme = "light" | "dark";
8
8
  /** Lifecycle state of a rendered thread item. */
9
9
  type MessageState = "typing" | "sending" | "sent" | "edited" | "deleted";
10
- /** Whether a thread item is a regular message or an app/system card. */
10
+ /** Whether a thread item is a regular message or a system/notice line. */
11
11
  type MessageVariant = "message" | "system";
12
- /** A system/app card payload (e.g. "Pull request opened" + action buttons). */
13
- interface SystemCard {
14
- /** Named card variant the skin renders, e.g. `"pr-opened"`. */
15
- card?: string;
16
- actions?: {
17
- label: string;
18
- href?: string;
19
- variant?: "primary" | "secondary";
20
- }[];
21
- }
22
12
  /** A reaction currently shown on a message. */
23
13
  interface RenderedReaction {
24
14
  emoji: string;
@@ -54,8 +44,6 @@ interface RenderedMessage {
54
44
  isGrouped: boolean;
55
45
  /** Display time in ms from timeline start. */
56
46
  atMs: number;
57
- /** Present when `variant === "system"`. */
58
- system?: SystemCard;
59
47
  }
60
48
  /** A typing indicator currently shown. */
61
49
  interface TypingState {
@@ -209,4 +197,4 @@ declare class TimelinePlayer implements Player {
209
197
  /** Create a real-time player over a `GetStateAt`. */
210
198
  declare function createPlayer(getStateAt: GetStateAt, options: PlayerOptions): Player;
211
199
 
212
- export { type ComposerState as C, type GetStateAt as G, type MessageVariant as M, type Player as P, type ResolvedTheme as R, type SystemCard as S, type TypingState as T, type RenderedMessage as a, type RenderedReaction as b, type SimState as c, type MessageState as d, type PlayerEvent as e, type PlayerEventMap as f, type PlayerOptions as g, type ScrollReason as h, type ScrollState as i, TimelinePlayer as j, createPlayer as k };
200
+ export { type ComposerState as C, type GetStateAt as G, type MessageVariant as M, type Player as P, type ResolvedTheme as R, type SimState as S, type TypingState as T, type RenderedMessage as a, type RenderedReaction as b, type MessageState as c, type PlayerEvent as d, type PlayerEventMap as e, type PlayerOptions as f, type ScrollReason as g, type ScrollState as h, TimelinePlayer as i, createPlayer as j };
package/dist/index.cjs CHANGED
@@ -55,6 +55,9 @@ function inlineText(span) {
55
55
  switch (span.type) {
56
56
  case "text":
57
57
  case "code":
58
+ case "bold":
59
+ case "italic":
60
+ case "strike":
58
61
  case "emoji":
59
62
  return span.value;
60
63
  case "mention":
@@ -63,10 +66,73 @@ function inlineText(span) {
63
66
  return span.label ?? span.href;
64
67
  }
65
68
  }
69
+ function spansText(spans) {
70
+ return spans.map(inlineText).join("");
71
+ }
72
+ function nodeText(node) {
73
+ switch (node.type) {
74
+ case "text":
75
+ return spansText(node.spans);
76
+ case "header":
77
+ return node.text;
78
+ case "section":
79
+ return spansText(node.spans ?? []);
80
+ case "context":
81
+ return node.elements.map((el) => el.type === "text" ? spansText(el.spans ?? []) : "").join(" ");
82
+ case "actions":
83
+ return node.elements.map((b) => b.label).join(" ");
84
+ case "codeblock":
85
+ return node.text;
86
+ case "attachment":
87
+ return node.content.map(nodeText).join(" ");
88
+ default:
89
+ return "";
90
+ }
91
+ }
66
92
  function plainText(content) {
67
- return content.map(
68
- (node) => node.type === "text" ? node.spans.map(inlineText).join("") : ""
69
- ).join(" ").trim();
93
+ return content.map(nodeText).join(" ").trim();
94
+ }
95
+ function resolveSpans(spans, names) {
96
+ return spans.map(
97
+ (s) => s.type === "mention" && s.id !== void 0 ? { type: "mention", id: s.id, label: `@${names.get(s.id) ?? s.id}` } : s
98
+ );
99
+ }
100
+ function resolveMentions(nodes, names) {
101
+ return nodes.map((node) => {
102
+ if (node.type === "text") {
103
+ const t = node;
104
+ return { ...t, spans: resolveSpans(t.spans, names) };
105
+ }
106
+ if (node.type === "section") {
107
+ const s = node;
108
+ return {
109
+ ...s,
110
+ spans: resolveSpans(s.spans ?? [], names),
111
+ ...s.fields ? {
112
+ fields: s.fields.map((f) => ({
113
+ spans: resolveSpans(f.spans ?? [], names)
114
+ }))
115
+ } : {}
116
+ };
117
+ }
118
+ if (node.type === "context") {
119
+ const c = node;
120
+ return {
121
+ ...c,
122
+ elements: c.elements.map(
123
+ (el) => el.type === "text" ? {
124
+ type: "text",
125
+ spans: resolveSpans(el.spans ?? [], names)
126
+ } : el
127
+ )
128
+ };
129
+ }
130
+ if (node.type === "attachment") {
131
+ const a = node;
132
+ return { ...a, content: resolveMentions(a.content, names) };
133
+ }
134
+ return node;
135
+ });
70
136
  }
71
137
  var cache = /* @__PURE__ */ new WeakMap();
72
138
  function compile(config) {
@@ -78,6 +144,7 @@ function compile(config) {
78
144
  config.participants.filter((p) => p.isSelf).map((p) => p.id)
79
145
  );
80
146
  const nameById = new Map(config.participants.map((p) => [p.id, p.name]));
147
+ const resolveContent = (body) => resolveMentions(schema.toContentNodes(body), nameById);
81
148
  const messages = [];
82
149
  const typings = [];
83
150
  const composers = [];
@@ -101,7 +168,8 @@ function compile(config) {
101
168
  case "system": {
102
169
  const isSelfMessage = step.type === "message" && selfIds.has(step.from) && !step.instant;
103
170
  if (isSelfMessage) {
104
- const text = plainText(schema.toContentNodes(step));
171
+ const content = resolveContent(step);
172
+ const text = plainText(content);
105
173
  const typingDur = typingDurationMs(text, pacing.typingCps);
106
174
  const sendAt = cursor + typingDur;
107
175
  const id2 = nextId(step.id);
@@ -118,7 +186,7 @@ function compile(config) {
118
186
  from: step.from,
119
187
  isSelf: true,
120
188
  variant: "message",
121
- content: schema.toContentNodes(step),
189
+ content,
122
190
  appearMs: sendAt,
123
191
  revealMs: SEND_REVEAL_MS,
124
192
  atMs: sendAt,
@@ -138,7 +206,7 @@ function compile(config) {
138
206
  appearAt = cursor + withJitter(rng, gap, pacing.humanize);
139
207
  }
140
208
  if (step.type === "message" && step.typing) {
141
- const showFor = (typeof step.typing === "object" ? step.typing.showTypingFor : void 0) ?? typingDurationMs(plainText(schema.toContentNodes(step)), pacing.typingCps);
209
+ const showFor = (typeof step.typing === "object" ? step.typing.showTypingFor : void 0) ?? typingDurationMs(plainText(resolveContent(step)), pacing.typingCps);
142
210
  typings.push({
143
211
  from: step.from,
144
212
  startMs: appearAt,
@@ -154,12 +222,11 @@ function compile(config) {
154
222
  from,
155
223
  isSelf: selfIds.has(from),
156
224
  variant: step.type === "system" ? "system" : "message",
157
- content: schema.toContentNodes(step),
225
+ content: resolveContent(step),
158
226
  appearMs: appearAt,
159
227
  revealMs: reveal,
160
228
  atMs: appearAt,
161
- reactions: [],
162
- ...step.type === "system" ? { system: { card: step.card, actions: step.actions } } : {}
229
+ reactions: []
163
230
  };
164
231
  messages.push(msg);
165
232
  byId.set(id, msg);
@@ -196,7 +263,7 @@ function compile(config) {
196
263
  from: sendFrom,
197
264
  isSelf: selfIds.has(sendFrom),
198
265
  variant: "message",
199
- content: schema.toContentNodes({ text: lastComposer.text }),
266
+ content: resolveContent({ text: lastComposer.text }),
200
267
  appearMs: cursor,
201
268
  revealMs: SEND_REVEAL_MS,
202
269
  atMs: cursor,
@@ -232,7 +299,7 @@ function compile(config) {
232
299
  const target = resolveTarget(step.target);
233
300
  if (target) {
234
301
  target.editedAtMs = cursor;
235
- target.editedContent = schema.toContentNodes(step);
302
+ target.editedContent = resolveContent(step);
236
303
  cursor += REVEAL_MS;
237
304
  }
238
305
  break;
@@ -300,8 +367,7 @@ function sampleState(compiled, t, theme) {
300
367
  reactions,
301
368
  isSelf: m.isSelf,
302
369
  isGrouped: previous !== void 0 && previous.from === m.from,
303
- atMs: m.atMs,
304
- ...m.system ? { system: m.system } : {}
370
+ atMs: m.atMs
305
371
  });
306
372
  if (m.appearMs > lastAppear) lastAppear = m.appearMs;
307
373
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine/rng.ts","../src/engine/pacing.ts","../src/engine/compile.ts","../src/engine/get-state-at.ts","../src/engine/capabilities.ts","../src/engine/create-player.ts","../src/engine/index.ts","../src/index.ts"],"names":["toContentNodes","id","msg"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Deterministic PRNG. The engine must never call `Math.random()` (PLAN §3) —\n * all jitter flows from the config `seed` through this, so `compile` is a pure\n * function of (config) and the same seed always yields the same timeline.\n */\n\n/** Mulberry32 — small, fast, fully deterministic. Returns floats in [0, 1). */\nexport function createRng(seed: number): () => number {\n let a = seed >>> 0;\n return function next(): number {\n a |= 0;\n a = (a + 0x6d2b79f5) | 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/**\n * Apply ±`fraction` jitter to a value, consuming one RNG draw. With\n * `fraction = 0` the value is returned unchanged (no draw consumed) so disabling\n * humanization is exact.\n */\nexport function withJitter(\n rng: () => number,\n value: number,\n fraction: number,\n): number {\n if (fraction <= 0) return value;\n const delta = (rng() * 2 - 1) * fraction;\n return value * (1 + delta);\n}\n","/**\n * Pacing helpers: convert text into typing/reading durations. Counting is by\n * **grapheme cluster** (not code unit) so emoji ZWJ sequences, combining marks,\n * and mixed scripts pace correctly (PLAN §20).\n */\n\ninterface SegmenterCtor {\n new (\n locales?: string,\n options?: { granularity?: \"grapheme\" | \"word\" | \"sentence\" },\n ): { segment(input: string): Iterable<unknown> };\n}\n\n/** Count grapheme clusters, preferring `Intl.Segmenter`, falling back to code points. */\nexport function graphemeCount(text: string): number {\n const Segmenter = (\n globalThis as unknown as { Intl?: { Segmenter?: SegmenterCtor } }\n ).Intl?.Segmenter;\n if (Segmenter) {\n let n = 0;\n for (const _ of new Segmenter(undefined, {\n granularity: \"grapheme\",\n }).segment(text)) {\n void _;\n n++;\n }\n return n;\n }\n return [...text].length;\n}\n\n/** ms to type `text` at `cps` chars/sec (min one grapheme of time). */\nexport function typingDurationMs(text: string, cps: number): number {\n const chars = Math.max(1, graphemeCount(text));\n return (chars / cps) * 1000;\n}\n\n/**\n * ms to \"read\" `text` at `wpm` words/min — used as the gap before an incoming\n * message ≈ reading time of the prior message. Words ≈ graphemes / 5.\n */\nexport function readingDelayMs(text: string, wpm: number): number {\n const words = Math.max(1, graphemeCount(text) / 5);\n return (words / wpm) * 60000;\n}\n","import {\n toContentNodes,\n type Config,\n type ContentNode,\n type InlineNode,\n type TextNode,\n} from \"@typecaast/schema\";\nimport { createRng, withJitter } from \"./rng.js\";\nimport { readingDelayMs, typingDurationMs } from \"./pacing.js\";\nimport type {\n CompiledComposer,\n CompiledMessage,\n CompiledTimeline,\n} from \"./compiled.js\";\n\n/** Reveal animation duration for a newly appearing message (ms). */\nconst REVEAL_MS = 280;\n/** Faster reveal when the self participant sends (commit feels snappy). */\nconst SEND_REVEAL_MS = 180;\nconst REACTION_POP_MS = 200;\nconst DEFAULT_TYPING_MS = 1500;\n/**\n * Default lag for a reaction whose `delay` is left blank — same beat the\n * builder auto-prepends between added steps (see `addStepAutoPaced`).\n */\nconst DEFAULT_REACTION_LAG_MS = 1000;\n/** Padding after the last event so the final frame holds (ms). */\nconst TAIL_PAD_MS = 800;\n\nfunction inlineText(span: InlineNode): string {\n switch (span.type) {\n case \"text\":\n case \"code\":\n case \"emoji\":\n return span.value;\n case \"mention\":\n return span.label;\n case \"link\":\n return span.label ?? span.href;\n }\n}\n\n/** Flatten content nodes to plain text for pacing math. */\nfunction plainText(content: ContentNode[]): string {\n return content\n .map((node) =>\n node.type === \"text\"\n ? (node as TextNode).spans.map(inlineText).join(\"\")\n : \"\",\n )\n .join(\" \")\n .trim();\n}\n\nconst cache = new WeakMap<Config, CompiledTimeline>();\n\n/**\n * Resolve an authored, auto-paced config into an absolute timeline (PLAN §5).\n * Pure and memoized by config reference. Overrides (`instant`,\n * `typingDuration`, `showTypingFor`) win over computed values; all jitter is\n * seeded from `meta.seed`. Use a `delay` step to insert an explicit pause.\n *\n * A plain `message` step from the self participant is auto-rendered through\n * the composer (type-then-send) just like an explicit `composerType` + `send`\n * pair. Use `instant: true` to skip the composer animation. Use the explicit\n * `composerType`/`send` primitives only when you need the type-pause-retype\n * choreography.\n */\nexport function compile(config: Config): CompiledTimeline {\n const cached = cache.get(config);\n if (cached) return cached;\n\n const pacing = config.pacing;\n const rng = createRng(config.meta.seed);\n const selfIds = new Set(\n config.participants.filter((p) => p.isSelf).map((p) => p.id),\n );\n const nameById = new Map(config.participants.map((p) => [p.id, p.name]));\n const messages: CompiledMessage[] = [];\n const typings: CompiledTimeline[\"typings\"] = [];\n const composers: CompiledComposer[] = [];\n const stepBoundaries: number[] = [];\n const byId = new Map<string, CompiledMessage>();\n\n // If the very first step is a message/system marked `instant`, the player\n // should open with that message already on screen — i.e. starting at t=0 —\n // rather than blank for `startDelayMs`.\n const firstStep = config.timeline[0];\n const firstStepIsInstantStart =\n firstStep !== undefined &&\n (firstStep.type === \"message\" || firstStep.type === \"system\") &&\n firstStep.instant === true;\n let cursor = firstStepIsInstantStart ? 0 : pacing.startDelayMs;\n let lastMessage: CompiledMessage | undefined;\n let lastComposer: CompiledComposer | undefined;\n let autoId = 0;\n const nextId = (explicit?: string): string => explicit ?? `auto-${autoId++}`;\n /**\n * Resolve a step's `target` to a compiled message. Blank/`undefined`/`$prev`\n * all mean \"the most-recent message\" so authors can leave the field empty in\n * the common case.\n */\n const resolveTarget = (target?: string): CompiledMessage | undefined => {\n if (!target || target === \"$prev\") return lastMessage;\n return byId.get(target);\n };\n\n for (const step of config.timeline) {\n stepBoundaries.push(cursor);\n\n switch (step.type) {\n case \"message\":\n case \"system\": {\n // Self messages are auto-rendered through the composer (type-then-send)\n // unless `instant` is set. This is pure sugar for an explicit\n // `composerType` + `send` pair, so timing matches: typing begins right\n // at the cursor with no auto-paced gap added on top. Keep the explicit\n // composerType+send pair available for the type-pause-retype case.\n const isSelfMessage =\n step.type === \"message\" && selfIds.has(step.from) && !step.instant;\n if (isSelfMessage) {\n const text = plainText(toContentNodes(step));\n const typingDur = typingDurationMs(text, pacing.typingCps);\n const sendAt = cursor + typingDur;\n const id = nextId(step.id);\n const comp: CompiledComposer = {\n from: step.from,\n text,\n startMs: cursor,\n endMs: sendAt,\n sendMs: sendAt,\n };\n composers.push(comp);\n const msg: CompiledMessage = {\n id,\n from: step.from,\n isSelf: true,\n variant: \"message\",\n content: toContentNodes(step),\n appearMs: sendAt,\n revealMs: SEND_REVEAL_MS,\n atMs: sendAt,\n reactions: [],\n };\n messages.push(msg);\n byId.set(id, msg);\n lastMessage = msg;\n lastComposer = undefined;\n cursor = sendAt + SEND_REVEAL_MS;\n break;\n }\n\n let appearAt: number;\n if (step.instant) appearAt = cursor;\n else {\n // Auto-paced gap = simulated reading time of the prior message. For\n // explicit beats use a `delay` step.\n const gap = lastMessage\n ? readingDelayMs(plainText(lastMessage.content), pacing.readingWpm)\n : 0;\n appearAt = cursor + withJitter(rng, gap, pacing.humanize);\n }\n\n if (step.type === \"message\" && step.typing) {\n const showFor =\n (typeof step.typing === \"object\"\n ? step.typing.showTypingFor\n : undefined) ??\n typingDurationMs(plainText(toContentNodes(step)), pacing.typingCps);\n typings.push({\n from: step.from,\n startMs: appearAt,\n endMs: appearAt + showFor,\n });\n appearAt += showFor;\n }\n\n const id = nextId(step.id);\n const reveal = step.instant ? 0 : REVEAL_MS;\n const from =\n step.type === \"system\" ? (step.from ?? \"system\") : step.from;\n const msg: CompiledMessage = {\n id,\n from,\n isSelf: selfIds.has(from),\n variant: step.type === \"system\" ? \"system\" : \"message\",\n content: toContentNodes(step),\n appearMs: appearAt,\n revealMs: reveal,\n atMs: appearAt,\n reactions: [],\n ...(step.type === \"system\"\n ? { system: { card: step.card, actions: step.actions } }\n : {}),\n };\n messages.push(msg);\n byId.set(id, msg);\n lastMessage = msg;\n cursor = appearAt + reveal;\n break;\n }\n\n case \"typing\": {\n const dur =\n step.showTypingFor ??\n withJitter(rng, DEFAULT_TYPING_MS, pacing.humanize);\n typings.push({ from: step.from, startMs: cursor, endMs: cursor + dur });\n cursor += dur;\n break;\n }\n\n case \"composerType\": {\n const dur =\n step.typingDuration ?? typingDurationMs(step.text, pacing.typingCps);\n const comp: CompiledComposer = {\n from: step.from,\n text: step.text,\n startMs: cursor,\n endMs: cursor + dur,\n };\n composers.push(comp);\n lastComposer = comp;\n cursor += dur;\n break;\n }\n\n case \"send\": {\n if (lastComposer) {\n lastComposer.sendMs = cursor;\n const id = nextId(step.id);\n // A send commits whatever's in the composer, so the message is always\n // from whoever was typing — never the step's own `from` (a stray\n // self-default there used to mis-attribute the sent message).\n const sendFrom = lastComposer.from;\n const msg: CompiledMessage = {\n id,\n from: sendFrom,\n isSelf: selfIds.has(sendFrom),\n variant: \"message\",\n content: toContentNodes({ text: lastComposer.text }),\n appearMs: cursor,\n revealMs: SEND_REVEAL_MS,\n atMs: cursor,\n reactions: [],\n };\n messages.push(msg);\n byId.set(id, msg);\n lastMessage = msg;\n cursor += SEND_REVEAL_MS;\n lastComposer = undefined;\n }\n break;\n }\n\n case \"reaction\": {\n const target = resolveTarget(step.target);\n if (target) {\n // Default lag mirrors the builder's auto-prepended delay between\n // steps so reactions land with a natural beat unless overridden.\n const delay =\n step.delay ??\n withJitter(rng, DEFAULT_REACTION_LAG_MS, pacing.humanize);\n const appearAt = target.appearMs + target.revealMs + delay;\n const by = step.from ? [step.from] : [];\n target.reactions.push({\n emoji: step.emoji,\n ...(step.shortcode ? { shortcode: step.shortcode } : {}),\n by,\n byNames: by.map((id) => nameById.get(id) ?? id),\n appearMs: appearAt,\n popMs: REACTION_POP_MS,\n });\n cursor = Math.max(cursor, appearAt + REACTION_POP_MS);\n }\n break;\n }\n\n case \"edit\": {\n const target = resolveTarget(step.target);\n if (target) {\n // Edits/deletes happen at the cursor; insert a `delay` step before\n // them to add breathing room.\n target.editedAtMs = cursor;\n target.editedContent = toContentNodes(step);\n cursor += REVEAL_MS;\n }\n break;\n }\n\n case \"delete\": {\n const target = resolveTarget(step.target);\n if (target) {\n target.deletedAtMs = cursor;\n }\n break;\n }\n\n case \"readReceipt\": {\n // No timeline advancement; receipts are visual-only and overlay the\n // current frame.\n break;\n }\n\n case \"delay\": {\n cursor += step.duration;\n break;\n }\n }\n }\n\n const compiled: CompiledTimeline = {\n messages,\n typings,\n composers,\n durationMs: cursor + TAIL_PAD_MS,\n stepBoundaries,\n };\n cache.set(config, compiled);\n return compiled;\n}\n","import type { GetStateAt } from \"../player.js\";\nimport type {\n RenderedMessage,\n RenderedReaction,\n ResolvedTheme,\n SimState,\n TypingState,\n} from \"../sim-state.js\";\nimport type { CompiledTimeline } from \"./compiled.js\";\n\nconst clamp01 = (x: number): number => (x < 0 ? 0 : x > 1 ? 1 : x);\n\n/** Approximate row height used for the scroll target (skins reflow on top). */\nconst ROW_HEIGHT = 64;\n/** Window after an event during which the scroll reason flags it. */\nconst SCROLL_FLAG_MS = 300;\n\n/**\n * Sample the complete renderable state at time `t` from a compiled timeline —\n * the engine's pure function of time (PLAN §3). No `Date.now()`, no mutation;\n * the same `(compiled, t, theme)` always yields a deep-equal `SimState`.\n */\nexport function sampleState(\n compiled: CompiledTimeline,\n t: number,\n theme: ResolvedTheme,\n): SimState {\n const messages: RenderedMessage[] = [];\n let lastAppear = 0;\n let reactionRecently = false;\n\n for (const m of compiled.messages) {\n if (m.appearMs > t) continue;\n if (m.deletedAtMs !== undefined && t >= m.deletedAtMs) continue;\n\n const edited =\n m.editedAtMs !== undefined &&\n m.editedContent !== undefined &&\n t >= m.editedAtMs;\n\n const reactions: RenderedReaction[] = [];\n for (const r of m.reactions) {\n if (r.appearMs > t) continue;\n reactions.push({\n emoji: r.emoji,\n ...(r.shortcode ? { shortcode: r.shortcode } : {}),\n count: r.by.length || 1,\n by: r.by,\n byNames: r.byNames,\n progress: r.popMs === 0 ? 1 : clamp01((t - r.appearMs) / r.popMs),\n });\n if (t - r.appearMs < SCROLL_FLAG_MS) reactionRecently = true;\n }\n\n const previous = messages[messages.length - 1];\n messages.push({\n id: m.id,\n from: m.from,\n variant: m.variant,\n content: edited ? m.editedContent! : m.content,\n revealProgress:\n m.revealMs === 0 ? 1 : clamp01((t - m.appearMs) / m.revealMs),\n state: edited ? \"edited\" : \"sent\",\n reactions,\n isSelf: m.isSelf,\n isGrouped: previous !== undefined && previous.from === m.from,\n atMs: m.atMs,\n ...(m.system ? { system: m.system } : {}),\n });\n\n if (m.appearMs > lastAppear) lastAppear = m.appearMs;\n }\n\n const typingIndicators: TypingState[] = [];\n for (const ty of compiled.typings) {\n if (t >= ty.startMs && t < ty.endMs) {\n const span = ty.endMs - ty.startMs;\n typingIndicators.push({\n from: ty.from,\n progress: span <= 0 ? 1 : clamp01((t - ty.startMs) / span),\n });\n }\n }\n\n // Composer: the latest one whose window contains t and hasn't yet sent.\n let composer: SimState[\"composer\"] = {\n text: \"\",\n caret: 0,\n sending: false,\n };\n for (const c of compiled.composers) {\n const end = c.sendMs ?? Number.POSITIVE_INFINITY;\n if (t < c.startMs || t >= end) continue;\n // Reveal by code point (not UTF-16 unit) so an astral emoji (🎬, 🚀) is\n // never split into a lone surrogate mid-type — that renders as a \"missing\n // glyph\" (□ / blue diamond) until the rest of the pair appears.\n const chars = [...c.text];\n const text =\n t >= c.endMs\n ? c.text\n : chars\n .slice(\n 0,\n Math.round(\n clamp01((t - c.startMs) / Math.max(1, c.endMs - c.startMs)) *\n chars.length,\n ),\n )\n .join(\"\");\n composer = {\n from: c.from,\n text,\n caret: text.length,\n sending: c.sendMs !== undefined && t >= c.endMs,\n };\n }\n\n const reason: SimState[\"scroll\"][\"reason\"] =\n messages.length > 0 && t - lastAppear < SCROLL_FLAG_MS\n ? \"new-message\"\n : reactionRecently\n ? \"reaction\"\n : \"none\";\n\n return {\n messages,\n typingIndicators,\n composer,\n scroll: { targetOffset: messages.length * ROW_HEIGHT, reason },\n durationMs: compiled.durationMs,\n theme,\n };\n}\n\n/** Bind a compiled timeline + theme into a `GetStateAt` closure. */\nexport function createGetStateAt(\n compiled: CompiledTimeline,\n theme: ResolvedTheme = \"light\",\n): GetStateAt {\n return (t: number) => sampleState(compiled, t, theme);\n}\n","import type { StepType } from \"@typecaast/schema\";\nimport type { CompiledTimeline } from \"./compiled.js\";\n\n/**\n * How a skin represents a given event type:\n * - `native`: a first-class affordance.\n * - `fallback`: a degraded but present form.\n * - `unsupported`: dropped from this skin's render (kept in the config).\n */\nexport type EventCapability = \"native\" | \"fallback\" | \"unsupported\";\n\n/** What a skin supports and how it represents each event/content type. */\nexport interface Capabilities {\n events: Partial<Record<StepType, EventCapability>>;\n /** Keyed by content node type (e.g. `image: true`, `videoEmbed: false`). */\n content: Partial<Record<string, boolean>>;\n reactions: boolean;\n threads: boolean;\n readReceipts: boolean;\n}\n\n/**\n * Apply a skin's capabilities to a compiled timeline: drop the events/content\n * the skin can't render, returning a new timeline (the original config is\n * untouched, so switching skins restores everything — PLAN §7). Timing is\n * preserved; only what's shown changes.\n */\nexport function resolveCapabilities(\n compiled: CompiledTimeline,\n caps: Capabilities,\n): CompiledTimeline {\n const ev = caps.events ?? {};\n const dropTyping = ev.typing === \"unsupported\";\n const dropReactions =\n caps.reactions === false || ev.reaction === \"unsupported\";\n const dropSystem = ev.system === \"unsupported\";\n const allowed = (type: string): boolean => caps.content?.[type] !== false;\n\n const messages = compiled.messages\n .filter((m) => !(dropSystem && m.variant === \"system\"))\n .map((m) => ({\n ...m,\n reactions: dropReactions ? [] : m.reactions,\n content: m.content.filter((n) => allowed(n.type)),\n ...(m.editedContent\n ? { editedContent: m.editedContent.filter((n) => allowed(n.type)) }\n : {}),\n }));\n\n return {\n ...compiled,\n messages,\n typings: dropTyping ? [] : compiled.typings,\n };\n}\n","import type {\n GetStateAt,\n Player,\n PlayerEvent,\n PlayerEventMap,\n} from \"../player.js\";\nimport type { SimState } from \"../sim-state.js\";\n\nexport interface PlayerOptions {\n durationMs: number;\n /** Step boundaries (ms) for stepNext/stepPrev. */\n steps?: number[];\n autoplay?: boolean;\n loop?: boolean;\n rate?: number;\n}\n\n/** A monotonic time source; reading it doesn't affect `getStateAt` determinism. */\nfunction now(): number {\n const perf = (globalThis as unknown as { performance?: { now(): number } })\n .performance;\n return perf ? perf.now() : Date.now();\n}\n\ntype FrameHandle = number;\n\ninterface SchedulerGlobals {\n requestAnimationFrame?: (cb: (time: number) => void) => number;\n cancelAnimationFrame?: (handle: number) => void;\n setTimeout?: (cb: () => void, ms: number) => number;\n clearTimeout?: (handle: number) => void;\n}\n\nfunction schedule(cb: () => void): FrameHandle {\n const g = globalThis as unknown as SchedulerGlobals;\n if (g.requestAnimationFrame) return g.requestAnimationFrame(() => cb());\n return g.setTimeout ? g.setTimeout(cb, 16) : 0;\n}\nfunction unschedule(handle: FrameHandle): void {\n const g = globalThis as unknown as SchedulerGlobals;\n if (g.cancelAnimationFrame) g.cancelAnimationFrame(handle);\n else if (g.clearTimeout) g.clearTimeout(handle);\n}\n\n/**\n * The real-time `Player`: a thin clock wrapper around a pure `GetStateAt`\n * (PLAN §5). It owns the only wall-clock in the system (rAF in the browser, a\n * timeout fallback elsewhere) and samples the engine each tick. The same class\n * drove the UI over the mock and now drives it over the real engine — identical\n * surface, so swapping the engine changes nothing here.\n */\nexport class TimelinePlayer implements Player {\n private readonly getStateAt: GetStateAt;\n private readonly _durationMs: number;\n private readonly steps: number[];\n private _currentMs = 0;\n private _rate: number;\n private _loop: boolean;\n private _playing = false;\n private _state: SimState;\n private anchor = 0;\n private frame: FrameHandle | null = null;\n private listeners = new Map<PlayerEvent, Set<(payload: never) => void>>();\n\n constructor(getStateAt: GetStateAt, options: PlayerOptions) {\n this.getStateAt = getStateAt;\n this._durationMs = options.durationMs;\n this.steps = (options.steps ?? [0, options.durationMs])\n .slice()\n .sort((a, b) => a - b);\n this._rate = options.rate ?? 1;\n this._loop = options.loop ?? false;\n this._state = getStateAt(0);\n if (options.autoplay) this.play();\n }\n\n get state(): SimState {\n return this._state;\n }\n get durationMs(): number {\n return this._durationMs;\n }\n get currentMs(): number {\n return this._currentMs;\n }\n get rate(): number {\n return this._rate;\n }\n get playing(): boolean {\n return this._playing;\n }\n get loop(): boolean {\n return this._loop;\n }\n\n play(): void {\n if (this._playing) return;\n this._playing = true;\n this.anchor = now() - this._currentMs / this._rate;\n this.emit(\"play\", undefined);\n this.tick();\n }\n\n pause(): void {\n if (!this._playing) return;\n this._playing = false;\n if (this.frame !== null) {\n unschedule(this.frame);\n this.frame = null;\n }\n this.emit(\"pause\", undefined);\n }\n\n private tick = (): void => {\n if (!this._playing) return;\n const elapsed = (now() - this.anchor) * this._rate;\n if (elapsed >= this._durationMs) {\n if (this._loop) {\n this._currentMs = 0;\n this.anchor = now();\n this.sampleAndEmit();\n this.frame = schedule(this.tick);\n return;\n }\n this._currentMs = this._durationMs;\n this.sampleAndEmit();\n this.pause();\n this.emit(\"end\", undefined);\n return;\n }\n this._currentMs = elapsed;\n this.sampleAndEmit();\n this.frame = schedule(this.tick);\n };\n\n private sampleAndEmit(): void {\n this._state = this.getStateAt(this._currentMs);\n this.emit(\"tick\", this._state);\n }\n\n private clamp(t: number): number {\n return t < 0 ? 0 : t > this._durationMs ? this._durationMs : t;\n }\n\n seek(timeMs: number): void {\n this._currentMs = this.clamp(timeMs);\n this.anchor = now() - this._currentMs / this._rate;\n this.sampleAndEmit();\n this.emit(\"seek\", this._currentMs);\n }\n\n scrubTo(timeMs: number): void {\n this.seek(timeMs);\n }\n\n setRate(rate: number): void {\n this._rate = rate <= 0 ? 1 : rate;\n this.anchor = now() - this._currentMs / this._rate;\n }\n\n setLoop(loop: boolean): void {\n this._loop = loop;\n }\n\n stepNext(): void {\n const next = this.steps.find((s) => s > this._currentMs + 1e-6);\n this.seek(next ?? this._durationMs);\n }\n\n stepPrev(): void {\n const prev = [...this.steps]\n .reverse()\n .find((s) => s < this._currentMs - 1e-6);\n this.seek(prev ?? 0);\n }\n\n on<E extends PlayerEvent>(\n event: E,\n listener: (payload: PlayerEventMap[E]) => void,\n ): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(listener as (payload: never) => void);\n return () => this.off(event, listener);\n }\n\n off<E extends PlayerEvent>(\n event: E,\n listener: (payload: PlayerEventMap[E]) => void,\n ): void {\n this.listeners.get(event)?.delete(listener as (payload: never) => void);\n }\n\n private emit<E extends PlayerEvent>(\n event: E,\n payload: PlayerEventMap[E],\n ): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const listener of set)\n (listener as (p: PlayerEventMap[E]) => void)(payload);\n }\n\n destroy(): void {\n this.pause();\n this.listeners.clear();\n }\n}\n\n/** Create a real-time player over a `GetStateAt`. */\nexport function createPlayer(\n getStateAt: GetStateAt,\n options: PlayerOptions,\n): Player {\n return new TimelinePlayer(getStateAt, options);\n}\n","import type { Config } from \"@typecaast/schema\";\nimport type { GetStateAt } from \"../player.js\";\nimport type { ResolvedTheme } from \"../sim-state.js\";\nimport type { Capabilities } from \"./capabilities.js\";\nimport { compile } from \"./compile.js\";\nimport { createGetStateAt } from \"./get-state-at.js\";\nimport { resolveCapabilities } from \"./capabilities.js\";\n\nexport { compile } from \"./compile.js\";\nexport { sampleState, createGetStateAt } from \"./get-state-at.js\";\nexport {\n createPlayer,\n TimelinePlayer,\n type PlayerOptions,\n} from \"./create-player.js\";\nexport { createRng, withJitter } from \"./rng.js\";\nexport { graphemeCount, typingDurationMs, readingDelayMs } from \"./pacing.js\";\nexport {\n resolveCapabilities,\n type Capabilities,\n type EventCapability,\n} from \"./capabilities.js\";\nexport type * from \"./compiled.js\";\n\n/** A ready-to-drive engine: a sampler plus what a player needs. */\nexport interface EngineHandle {\n getStateAt: GetStateAt;\n durationMs: number;\n /** Step boundaries for stepNext/stepPrev. */\n steps: number[];\n}\n\n/**\n * Compile a config and bind a theme into a ready engine — the one call a\n * renderer needs. `compile` is memoized, so re-creating an engine for the same\n * config (e.g. only the theme changed) is cheap.\n */\nexport function createEngine(\n config: Config,\n theme: ResolvedTheme = \"light\",\n capabilities?: Capabilities,\n): EngineHandle {\n let compiled = compile(config);\n if (capabilities) compiled = resolveCapabilities(compiled, capabilities);\n return {\n getStateAt: createGetStateAt(compiled, theme),\n durationMs: compiled.durationMs,\n steps: compiled.stepBoundaries,\n };\n}\n","/**\n * `@typecaast/core` — the framework-agnostic engine and, locked first, the\n * contracts the rest of the system builds against: `SimState` (the renderable\n * state), the skin-prop data types, and the `Player` interface.\n *\n * The engine implementation (`compile` + `getStateAt`) lands in M1-engine,\n * behind these same contracts.\n */\n\n/** Contract version for the SimState/Player/skin-prop surface. */\nexport const CORE_CONTRACT_VERSION = 1;\n\nexport type * from \"./sim-state.js\";\nexport type * from \"./skin-props.js\";\nexport type * from \"./player.js\";\n\n/** The engine: compile() + getStateAt() + createEngine(). */\nexport * from \"./engine/index.js\";\n"]}
1
+ {"version":3,"sources":["../src/engine/rng.ts","../src/engine/pacing.ts","../src/engine/compile.ts","../src/engine/get-state-at.ts","../src/engine/capabilities.ts","../src/engine/create-player.ts","../src/engine/index.ts","../src/index.ts"],"names":["toContentNodes","id","msg"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Deterministic PRNG. The engine must never call `Math.random()` (PLAN §3) —\n * all jitter flows from the config `seed` through this, so `compile` is a pure\n * function of (config) and the same seed always yields the same timeline.\n */\n\n/** Mulberry32 — small, fast, fully deterministic. Returns floats in [0, 1). */\nexport function createRng(seed: number): () => number {\n let a = seed >>> 0;\n return function next(): number {\n a |= 0;\n a = (a + 0x6d2b79f5) | 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/**\n * Apply ±`fraction` jitter to a value, consuming one RNG draw. With\n * `fraction = 0` the value is returned unchanged (no draw consumed) so disabling\n * humanization is exact.\n */\nexport function withJitter(\n rng: () => number,\n value: number,\n fraction: number,\n): number {\n if (fraction <= 0) return value;\n const delta = (rng() * 2 - 1) * fraction;\n return value * (1 + delta);\n}\n","/**\n * Pacing helpers: convert text into typing/reading durations. Counting is by\n * **grapheme cluster** (not code unit) so emoji ZWJ sequences, combining marks,\n * and mixed scripts pace correctly (PLAN §20).\n */\n\ninterface SegmenterCtor {\n new (\n locales?: string,\n options?: { granularity?: \"grapheme\" | \"word\" | \"sentence\" },\n ): { segment(input: string): Iterable<unknown> };\n}\n\n/** Count grapheme clusters, preferring `Intl.Segmenter`, falling back to code points. */\nexport function graphemeCount(text: string): number {\n const Segmenter = (\n globalThis as unknown as { Intl?: { Segmenter?: SegmenterCtor } }\n ).Intl?.Segmenter;\n if (Segmenter) {\n let n = 0;\n for (const _ of new Segmenter(undefined, {\n granularity: \"grapheme\",\n }).segment(text)) {\n void _;\n n++;\n }\n return n;\n }\n return [...text].length;\n}\n\n/** ms to type `text` at `cps` chars/sec (min one grapheme of time). */\nexport function typingDurationMs(text: string, cps: number): number {\n const chars = Math.max(1, graphemeCount(text));\n return (chars / cps) * 1000;\n}\n\n/**\n * ms to \"read\" `text` at `wpm` words/min — used as the gap before an incoming\n * message ≈ reading time of the prior message. Words ≈ graphemes / 5.\n */\nexport function readingDelayMs(text: string, wpm: number): number {\n const words = Math.max(1, graphemeCount(text) / 5);\n return (words / wpm) * 60000;\n}\n","import {\n toContentNodes,\n type ActionsNode,\n type AttachmentNode,\n type CodeBlockNode,\n type Config,\n type ContentNode,\n type ContextNode,\n type HeaderNode,\n type InlineNode,\n type SectionNode,\n type TextNode,\n} from \"@typecaast/schema\";\nimport { createRng, withJitter } from \"./rng.js\";\nimport { readingDelayMs, typingDurationMs } from \"./pacing.js\";\nimport type {\n CompiledComposer,\n CompiledMessage,\n CompiledTimeline,\n} from \"./compiled.js\";\n\n/** Reveal animation duration for a newly appearing message (ms). */\nconst REVEAL_MS = 280;\n/** Faster reveal when the self participant sends (commit feels snappy). */\nconst SEND_REVEAL_MS = 180;\nconst REACTION_POP_MS = 200;\nconst DEFAULT_TYPING_MS = 1500;\n/**\n * Default lag for a reaction whose `delay` is left blank — same beat the\n * builder auto-prepends between added steps (see `addStepAutoPaced`).\n */\nconst DEFAULT_REACTION_LAG_MS = 1000;\n/** Padding after the last event so the final frame holds (ms). */\nconst TAIL_PAD_MS = 800;\n\nfunction inlineText(span: InlineNode): string {\n switch (span.type) {\n case \"text\":\n case \"code\":\n case \"bold\":\n case \"italic\":\n case \"strike\":\n case \"emoji\":\n return span.value;\n case \"mention\":\n return span.label;\n case \"link\":\n return span.label ?? span.href;\n }\n}\n\n/** Concatenate a span list to plain text. */\nfunction spansText(spans: InlineNode[]): string {\n return spans.map(inlineText).join(\"\");\n}\n\n/** Flatten a single content node (incl. Block Kit blocks) to plain text. */\nfunction nodeText(node: ContentNode): string {\n switch (node.type) {\n case \"text\":\n return spansText((node as TextNode).spans);\n case \"header\":\n return (node as HeaderNode).text;\n case \"section\":\n return spansText((node as SectionNode).spans ?? []);\n case \"context\":\n return (node as ContextNode).elements\n .map((el) => (el.type === \"text\" ? spansText(el.spans ?? []) : \"\"))\n .join(\" \");\n case \"actions\":\n return (node as ActionsNode).elements.map((b) => b.label).join(\" \");\n case \"codeblock\":\n return (node as CodeBlockNode).text;\n case \"attachment\":\n return (node as AttachmentNode).content.map(nodeText).join(\" \");\n default:\n return \"\"; // image, divider, unknown — no readable text\n }\n}\n\n/** Flatten content nodes to plain text for pacing math. */\nfunction plainText(content: ContentNode[]): string {\n return content.map(nodeText).join(\" \").trim();\n}\n\n/** Resolve `<@id>` mentions to the participant's display name. */\nfunction resolveSpans(\n spans: InlineNode[],\n names: Map<string, string>,\n): InlineNode[] {\n return spans.map((s) =>\n s.type === \"mention\" && s.id !== undefined\n ? { type: \"mention\", id: s.id, label: `@${names.get(s.id) ?? s.id}` }\n : s,\n );\n}\n\n/** Walk content nodes resolving mention labels (recurses into attachments). */\nfunction resolveMentions(\n nodes: ContentNode[],\n names: Map<string, string>,\n): ContentNode[] {\n return nodes.map((node) => {\n if (node.type === \"text\") {\n const t = node as TextNode;\n return { ...t, spans: resolveSpans(t.spans, names) };\n }\n if (node.type === \"section\") {\n const s = node as SectionNode;\n return {\n ...s,\n spans: resolveSpans(s.spans ?? [], names),\n ...(s.fields\n ? {\n fields: s.fields.map((f) => ({\n spans: resolveSpans(f.spans ?? [], names),\n })),\n }\n : {}),\n };\n }\n if (node.type === \"context\") {\n const c = node as ContextNode;\n return {\n ...c,\n elements: c.elements.map((el) =>\n el.type === \"text\"\n ? {\n type: \"text\" as const,\n spans: resolveSpans(el.spans ?? [], names),\n }\n : el,\n ),\n };\n }\n if (node.type === \"attachment\") {\n const a = node as AttachmentNode;\n return { ...a, content: resolveMentions(a.content, names) };\n }\n return node;\n });\n}\n\nconst cache = new WeakMap<Config, CompiledTimeline>();\n\n/**\n * Resolve an authored, auto-paced config into an absolute timeline (PLAN §5).\n * Pure and memoized by config reference. Overrides (`instant`,\n * `typingDuration`, `showTypingFor`) win over computed values; all jitter is\n * seeded from `meta.seed`. Use a `delay` step to insert an explicit pause.\n *\n * A plain `message` step from the self participant is auto-rendered through\n * the composer (type-then-send) just like an explicit `composerType` + `send`\n * pair. Use `instant: true` to skip the composer animation. Use the explicit\n * `composerType`/`send` primitives only when you need the type-pause-retype\n * choreography.\n */\nexport function compile(config: Config): CompiledTimeline {\n const cached = cache.get(config);\n if (cached) return cached;\n\n const pacing = config.pacing;\n const rng = createRng(config.meta.seed);\n const selfIds = new Set(\n config.participants.filter((p) => p.isSelf).map((p) => p.id),\n );\n const nameById = new Map(config.participants.map((p) => [p.id, p.name]));\n /** Resolve a step's body sugar to content nodes with mentions bound. */\n const resolveContent = (\n body: Parameters<typeof toContentNodes>[0],\n ): ContentNode[] => resolveMentions(toContentNodes(body), nameById);\n const messages: CompiledMessage[] = [];\n const typings: CompiledTimeline[\"typings\"] = [];\n const composers: CompiledComposer[] = [];\n const stepBoundaries: number[] = [];\n const byId = new Map<string, CompiledMessage>();\n\n // If the very first step is a message/system marked `instant`, the player\n // should open with that message already on screen — i.e. starting at t=0 —\n // rather than blank for `startDelayMs`.\n const firstStep = config.timeline[0];\n const firstStepIsInstantStart =\n firstStep !== undefined &&\n (firstStep.type === \"message\" || firstStep.type === \"system\") &&\n firstStep.instant === true;\n let cursor = firstStepIsInstantStart ? 0 : pacing.startDelayMs;\n let lastMessage: CompiledMessage | undefined;\n let lastComposer: CompiledComposer | undefined;\n let autoId = 0;\n const nextId = (explicit?: string): string => explicit ?? `auto-${autoId++}`;\n /**\n * Resolve a step's `target` to a compiled message. Blank/`undefined`/`$prev`\n * all mean \"the most-recent message\" so authors can leave the field empty in\n * the common case.\n */\n const resolveTarget = (target?: string): CompiledMessage | undefined => {\n if (!target || target === \"$prev\") return lastMessage;\n return byId.get(target);\n };\n\n for (const step of config.timeline) {\n stepBoundaries.push(cursor);\n\n switch (step.type) {\n case \"message\":\n case \"system\": {\n // Self messages are auto-rendered through the composer (type-then-send)\n // unless `instant` is set. This is pure sugar for an explicit\n // `composerType` + `send` pair, so timing matches: typing begins right\n // at the cursor with no auto-paced gap added on top. Keep the explicit\n // composerType+send pair available for the type-pause-retype case.\n const isSelfMessage =\n step.type === \"message\" && selfIds.has(step.from) && !step.instant;\n if (isSelfMessage) {\n const content = resolveContent(step);\n const text = plainText(content);\n const typingDur = typingDurationMs(text, pacing.typingCps);\n const sendAt = cursor + typingDur;\n const id = nextId(step.id);\n const comp: CompiledComposer = {\n from: step.from,\n text,\n startMs: cursor,\n endMs: sendAt,\n sendMs: sendAt,\n };\n composers.push(comp);\n const msg: CompiledMessage = {\n id,\n from: step.from,\n isSelf: true,\n variant: \"message\",\n content,\n appearMs: sendAt,\n revealMs: SEND_REVEAL_MS,\n atMs: sendAt,\n reactions: [],\n };\n messages.push(msg);\n byId.set(id, msg);\n lastMessage = msg;\n lastComposer = undefined;\n cursor = sendAt + SEND_REVEAL_MS;\n break;\n }\n\n let appearAt: number;\n if (step.instant) appearAt = cursor;\n else {\n // Auto-paced gap = simulated reading time of the prior message. For\n // explicit beats use a `delay` step.\n const gap = lastMessage\n ? readingDelayMs(plainText(lastMessage.content), pacing.readingWpm)\n : 0;\n appearAt = cursor + withJitter(rng, gap, pacing.humanize);\n }\n\n if (step.type === \"message\" && step.typing) {\n const showFor =\n (typeof step.typing === \"object\"\n ? step.typing.showTypingFor\n : undefined) ??\n typingDurationMs(plainText(resolveContent(step)), pacing.typingCps);\n typings.push({\n from: step.from,\n startMs: appearAt,\n endMs: appearAt + showFor,\n });\n appearAt += showFor;\n }\n\n const id = nextId(step.id);\n const reveal = step.instant ? 0 : REVEAL_MS;\n const from =\n step.type === \"system\" ? (step.from ?? \"system\") : step.from;\n const msg: CompiledMessage = {\n id,\n from,\n isSelf: selfIds.has(from),\n variant: step.type === \"system\" ? \"system\" : \"message\",\n content: resolveContent(step),\n appearMs: appearAt,\n revealMs: reveal,\n atMs: appearAt,\n reactions: [],\n };\n messages.push(msg);\n byId.set(id, msg);\n lastMessage = msg;\n cursor = appearAt + reveal;\n break;\n }\n\n case \"typing\": {\n const dur =\n step.showTypingFor ??\n withJitter(rng, DEFAULT_TYPING_MS, pacing.humanize);\n typings.push({ from: step.from, startMs: cursor, endMs: cursor + dur });\n cursor += dur;\n break;\n }\n\n case \"composerType\": {\n const dur =\n step.typingDuration ?? typingDurationMs(step.text, pacing.typingCps);\n const comp: CompiledComposer = {\n from: step.from,\n text: step.text,\n startMs: cursor,\n endMs: cursor + dur,\n };\n composers.push(comp);\n lastComposer = comp;\n cursor += dur;\n break;\n }\n\n case \"send\": {\n if (lastComposer) {\n lastComposer.sendMs = cursor;\n const id = nextId(step.id);\n // A send commits whatever's in the composer, so the message is always\n // from whoever was typing — never the step's own `from` (a stray\n // self-default there used to mis-attribute the sent message).\n const sendFrom = lastComposer.from;\n const msg: CompiledMessage = {\n id,\n from: sendFrom,\n isSelf: selfIds.has(sendFrom),\n variant: \"message\",\n content: resolveContent({ text: lastComposer.text }),\n appearMs: cursor,\n revealMs: SEND_REVEAL_MS,\n atMs: cursor,\n reactions: [],\n };\n messages.push(msg);\n byId.set(id, msg);\n lastMessage = msg;\n cursor += SEND_REVEAL_MS;\n lastComposer = undefined;\n }\n break;\n }\n\n case \"reaction\": {\n const target = resolveTarget(step.target);\n if (target) {\n // Default lag mirrors the builder's auto-prepended delay between\n // steps so reactions land with a natural beat unless overridden.\n const delay =\n step.delay ??\n withJitter(rng, DEFAULT_REACTION_LAG_MS, pacing.humanize);\n const appearAt = target.appearMs + target.revealMs + delay;\n const by = step.from ? [step.from] : [];\n target.reactions.push({\n emoji: step.emoji,\n ...(step.shortcode ? { shortcode: step.shortcode } : {}),\n by,\n byNames: by.map((id) => nameById.get(id) ?? id),\n appearMs: appearAt,\n popMs: REACTION_POP_MS,\n });\n cursor = Math.max(cursor, appearAt + REACTION_POP_MS);\n }\n break;\n }\n\n case \"edit\": {\n const target = resolveTarget(step.target);\n if (target) {\n // Edits/deletes happen at the cursor; insert a `delay` step before\n // them to add breathing room.\n target.editedAtMs = cursor;\n target.editedContent = resolveContent(step);\n cursor += REVEAL_MS;\n }\n break;\n }\n\n case \"delete\": {\n const target = resolveTarget(step.target);\n if (target) {\n target.deletedAtMs = cursor;\n }\n break;\n }\n\n case \"readReceipt\": {\n // No timeline advancement; receipts are visual-only and overlay the\n // current frame.\n break;\n }\n\n case \"delay\": {\n cursor += step.duration;\n break;\n }\n }\n }\n\n const compiled: CompiledTimeline = {\n messages,\n typings,\n composers,\n durationMs: cursor + TAIL_PAD_MS,\n stepBoundaries,\n };\n cache.set(config, compiled);\n return compiled;\n}\n","import type { GetStateAt } from \"../player.js\";\nimport type {\n RenderedMessage,\n RenderedReaction,\n ResolvedTheme,\n SimState,\n TypingState,\n} from \"../sim-state.js\";\nimport type { CompiledTimeline } from \"./compiled.js\";\n\nconst clamp01 = (x: number): number => (x < 0 ? 0 : x > 1 ? 1 : x);\n\n/** Approximate row height used for the scroll target (skins reflow on top). */\nconst ROW_HEIGHT = 64;\n/** Window after an event during which the scroll reason flags it. */\nconst SCROLL_FLAG_MS = 300;\n\n/**\n * Sample the complete renderable state at time `t` from a compiled timeline —\n * the engine's pure function of time (PLAN §3). No `Date.now()`, no mutation;\n * the same `(compiled, t, theme)` always yields a deep-equal `SimState`.\n */\nexport function sampleState(\n compiled: CompiledTimeline,\n t: number,\n theme: ResolvedTheme,\n): SimState {\n const messages: RenderedMessage[] = [];\n let lastAppear = 0;\n let reactionRecently = false;\n\n for (const m of compiled.messages) {\n if (m.appearMs > t) continue;\n if (m.deletedAtMs !== undefined && t >= m.deletedAtMs) continue;\n\n const edited =\n m.editedAtMs !== undefined &&\n m.editedContent !== undefined &&\n t >= m.editedAtMs;\n\n const reactions: RenderedReaction[] = [];\n for (const r of m.reactions) {\n if (r.appearMs > t) continue;\n reactions.push({\n emoji: r.emoji,\n ...(r.shortcode ? { shortcode: r.shortcode } : {}),\n count: r.by.length || 1,\n by: r.by,\n byNames: r.byNames,\n progress: r.popMs === 0 ? 1 : clamp01((t - r.appearMs) / r.popMs),\n });\n if (t - r.appearMs < SCROLL_FLAG_MS) reactionRecently = true;\n }\n\n const previous = messages[messages.length - 1];\n messages.push({\n id: m.id,\n from: m.from,\n variant: m.variant,\n content: edited ? m.editedContent! : m.content,\n revealProgress:\n m.revealMs === 0 ? 1 : clamp01((t - m.appearMs) / m.revealMs),\n state: edited ? \"edited\" : \"sent\",\n reactions,\n isSelf: m.isSelf,\n isGrouped: previous !== undefined && previous.from === m.from,\n atMs: m.atMs,\n });\n\n if (m.appearMs > lastAppear) lastAppear = m.appearMs;\n }\n\n const typingIndicators: TypingState[] = [];\n for (const ty of compiled.typings) {\n if (t >= ty.startMs && t < ty.endMs) {\n const span = ty.endMs - ty.startMs;\n typingIndicators.push({\n from: ty.from,\n progress: span <= 0 ? 1 : clamp01((t - ty.startMs) / span),\n });\n }\n }\n\n // Composer: the latest one whose window contains t and hasn't yet sent.\n let composer: SimState[\"composer\"] = {\n text: \"\",\n caret: 0,\n sending: false,\n };\n for (const c of compiled.composers) {\n const end = c.sendMs ?? Number.POSITIVE_INFINITY;\n if (t < c.startMs || t >= end) continue;\n // Reveal by code point (not UTF-16 unit) so an astral emoji (🎬, 🚀) is\n // never split into a lone surrogate mid-type — that renders as a \"missing\n // glyph\" (□ / blue diamond) until the rest of the pair appears.\n const chars = [...c.text];\n const text =\n t >= c.endMs\n ? c.text\n : chars\n .slice(\n 0,\n Math.round(\n clamp01((t - c.startMs) / Math.max(1, c.endMs - c.startMs)) *\n chars.length,\n ),\n )\n .join(\"\");\n composer = {\n from: c.from,\n text,\n caret: text.length,\n sending: c.sendMs !== undefined && t >= c.endMs,\n };\n }\n\n const reason: SimState[\"scroll\"][\"reason\"] =\n messages.length > 0 && t - lastAppear < SCROLL_FLAG_MS\n ? \"new-message\"\n : reactionRecently\n ? \"reaction\"\n : \"none\";\n\n return {\n messages,\n typingIndicators,\n composer,\n scroll: { targetOffset: messages.length * ROW_HEIGHT, reason },\n durationMs: compiled.durationMs,\n theme,\n };\n}\n\n/** Bind a compiled timeline + theme into a `GetStateAt` closure. */\nexport function createGetStateAt(\n compiled: CompiledTimeline,\n theme: ResolvedTheme = \"light\",\n): GetStateAt {\n return (t: number) => sampleState(compiled, t, theme);\n}\n","import type { StepType } from \"@typecaast/schema\";\nimport type { CompiledTimeline } from \"./compiled.js\";\n\n/**\n * How a skin represents a given event type:\n * - `native`: a first-class affordance.\n * - `fallback`: a degraded but present form.\n * - `unsupported`: dropped from this skin's render (kept in the config).\n */\nexport type EventCapability = \"native\" | \"fallback\" | \"unsupported\";\n\n/** What a skin supports and how it represents each event/content type. */\nexport interface Capabilities {\n events: Partial<Record<StepType, EventCapability>>;\n /** Keyed by content node type (e.g. `image: true`, `videoEmbed: false`). */\n content: Partial<Record<string, boolean>>;\n reactions: boolean;\n threads: boolean;\n readReceipts: boolean;\n}\n\n/**\n * Apply a skin's capabilities to a compiled timeline: drop the events/content\n * the skin can't render, returning a new timeline (the original config is\n * untouched, so switching skins restores everything — PLAN §7). Timing is\n * preserved; only what's shown changes.\n */\nexport function resolveCapabilities(\n compiled: CompiledTimeline,\n caps: Capabilities,\n): CompiledTimeline {\n const ev = caps.events ?? {};\n const dropTyping = ev.typing === \"unsupported\";\n const dropReactions =\n caps.reactions === false || ev.reaction === \"unsupported\";\n const dropSystem = ev.system === \"unsupported\";\n const allowed = (type: string): boolean => caps.content?.[type] !== false;\n\n const messages = compiled.messages\n .filter((m) => !(dropSystem && m.variant === \"system\"))\n .map((m) => ({\n ...m,\n reactions: dropReactions ? [] : m.reactions,\n content: m.content.filter((n) => allowed(n.type)),\n ...(m.editedContent\n ? { editedContent: m.editedContent.filter((n) => allowed(n.type)) }\n : {}),\n }));\n\n return {\n ...compiled,\n messages,\n typings: dropTyping ? [] : compiled.typings,\n };\n}\n","import type {\n GetStateAt,\n Player,\n PlayerEvent,\n PlayerEventMap,\n} from \"../player.js\";\nimport type { SimState } from \"../sim-state.js\";\n\nexport interface PlayerOptions {\n durationMs: number;\n /** Step boundaries (ms) for stepNext/stepPrev. */\n steps?: number[];\n autoplay?: boolean;\n loop?: boolean;\n rate?: number;\n}\n\n/** A monotonic time source; reading it doesn't affect `getStateAt` determinism. */\nfunction now(): number {\n const perf = (globalThis as unknown as { performance?: { now(): number } })\n .performance;\n return perf ? perf.now() : Date.now();\n}\n\ntype FrameHandle = number;\n\ninterface SchedulerGlobals {\n requestAnimationFrame?: (cb: (time: number) => void) => number;\n cancelAnimationFrame?: (handle: number) => void;\n setTimeout?: (cb: () => void, ms: number) => number;\n clearTimeout?: (handle: number) => void;\n}\n\nfunction schedule(cb: () => void): FrameHandle {\n const g = globalThis as unknown as SchedulerGlobals;\n if (g.requestAnimationFrame) return g.requestAnimationFrame(() => cb());\n return g.setTimeout ? g.setTimeout(cb, 16) : 0;\n}\nfunction unschedule(handle: FrameHandle): void {\n const g = globalThis as unknown as SchedulerGlobals;\n if (g.cancelAnimationFrame) g.cancelAnimationFrame(handle);\n else if (g.clearTimeout) g.clearTimeout(handle);\n}\n\n/**\n * The real-time `Player`: a thin clock wrapper around a pure `GetStateAt`\n * (PLAN §5). It owns the only wall-clock in the system (rAF in the browser, a\n * timeout fallback elsewhere) and samples the engine each tick. The same class\n * drove the UI over the mock and now drives it over the real engine — identical\n * surface, so swapping the engine changes nothing here.\n */\nexport class TimelinePlayer implements Player {\n private readonly getStateAt: GetStateAt;\n private readonly _durationMs: number;\n private readonly steps: number[];\n private _currentMs = 0;\n private _rate: number;\n private _loop: boolean;\n private _playing = false;\n private _state: SimState;\n private anchor = 0;\n private frame: FrameHandle | null = null;\n private listeners = new Map<PlayerEvent, Set<(payload: never) => void>>();\n\n constructor(getStateAt: GetStateAt, options: PlayerOptions) {\n this.getStateAt = getStateAt;\n this._durationMs = options.durationMs;\n this.steps = (options.steps ?? [0, options.durationMs])\n .slice()\n .sort((a, b) => a - b);\n this._rate = options.rate ?? 1;\n this._loop = options.loop ?? false;\n this._state = getStateAt(0);\n if (options.autoplay) this.play();\n }\n\n get state(): SimState {\n return this._state;\n }\n get durationMs(): number {\n return this._durationMs;\n }\n get currentMs(): number {\n return this._currentMs;\n }\n get rate(): number {\n return this._rate;\n }\n get playing(): boolean {\n return this._playing;\n }\n get loop(): boolean {\n return this._loop;\n }\n\n play(): void {\n if (this._playing) return;\n this._playing = true;\n this.anchor = now() - this._currentMs / this._rate;\n this.emit(\"play\", undefined);\n this.tick();\n }\n\n pause(): void {\n if (!this._playing) return;\n this._playing = false;\n if (this.frame !== null) {\n unschedule(this.frame);\n this.frame = null;\n }\n this.emit(\"pause\", undefined);\n }\n\n private tick = (): void => {\n if (!this._playing) return;\n const elapsed = (now() - this.anchor) * this._rate;\n if (elapsed >= this._durationMs) {\n if (this._loop) {\n this._currentMs = 0;\n this.anchor = now();\n this.sampleAndEmit();\n this.frame = schedule(this.tick);\n return;\n }\n this._currentMs = this._durationMs;\n this.sampleAndEmit();\n this.pause();\n this.emit(\"end\", undefined);\n return;\n }\n this._currentMs = elapsed;\n this.sampleAndEmit();\n this.frame = schedule(this.tick);\n };\n\n private sampleAndEmit(): void {\n this._state = this.getStateAt(this._currentMs);\n this.emit(\"tick\", this._state);\n }\n\n private clamp(t: number): number {\n return t < 0 ? 0 : t > this._durationMs ? this._durationMs : t;\n }\n\n seek(timeMs: number): void {\n this._currentMs = this.clamp(timeMs);\n this.anchor = now() - this._currentMs / this._rate;\n this.sampleAndEmit();\n this.emit(\"seek\", this._currentMs);\n }\n\n scrubTo(timeMs: number): void {\n this.seek(timeMs);\n }\n\n setRate(rate: number): void {\n this._rate = rate <= 0 ? 1 : rate;\n this.anchor = now() - this._currentMs / this._rate;\n }\n\n setLoop(loop: boolean): void {\n this._loop = loop;\n }\n\n stepNext(): void {\n const next = this.steps.find((s) => s > this._currentMs + 1e-6);\n this.seek(next ?? this._durationMs);\n }\n\n stepPrev(): void {\n const prev = [...this.steps]\n .reverse()\n .find((s) => s < this._currentMs - 1e-6);\n this.seek(prev ?? 0);\n }\n\n on<E extends PlayerEvent>(\n event: E,\n listener: (payload: PlayerEventMap[E]) => void,\n ): () => void {\n let set = this.listeners.get(event);\n if (!set) {\n set = new Set();\n this.listeners.set(event, set);\n }\n set.add(listener as (payload: never) => void);\n return () => this.off(event, listener);\n }\n\n off<E extends PlayerEvent>(\n event: E,\n listener: (payload: PlayerEventMap[E]) => void,\n ): void {\n this.listeners.get(event)?.delete(listener as (payload: never) => void);\n }\n\n private emit<E extends PlayerEvent>(\n event: E,\n payload: PlayerEventMap[E],\n ): void {\n const set = this.listeners.get(event);\n if (!set) return;\n for (const listener of set)\n (listener as (p: PlayerEventMap[E]) => void)(payload);\n }\n\n destroy(): void {\n this.pause();\n this.listeners.clear();\n }\n}\n\n/** Create a real-time player over a `GetStateAt`. */\nexport function createPlayer(\n getStateAt: GetStateAt,\n options: PlayerOptions,\n): Player {\n return new TimelinePlayer(getStateAt, options);\n}\n","import type { Config } from \"@typecaast/schema\";\nimport type { GetStateAt } from \"../player.js\";\nimport type { ResolvedTheme } from \"../sim-state.js\";\nimport type { Capabilities } from \"./capabilities.js\";\nimport { compile } from \"./compile.js\";\nimport { createGetStateAt } from \"./get-state-at.js\";\nimport { resolveCapabilities } from \"./capabilities.js\";\n\nexport { compile } from \"./compile.js\";\nexport { sampleState, createGetStateAt } from \"./get-state-at.js\";\nexport {\n createPlayer,\n TimelinePlayer,\n type PlayerOptions,\n} from \"./create-player.js\";\nexport { createRng, withJitter } from \"./rng.js\";\nexport { graphemeCount, typingDurationMs, readingDelayMs } from \"./pacing.js\";\nexport {\n resolveCapabilities,\n type Capabilities,\n type EventCapability,\n} from \"./capabilities.js\";\nexport type * from \"./compiled.js\";\n\n/** A ready-to-drive engine: a sampler plus what a player needs. */\nexport interface EngineHandle {\n getStateAt: GetStateAt;\n durationMs: number;\n /** Step boundaries for stepNext/stepPrev. */\n steps: number[];\n}\n\n/**\n * Compile a config and bind a theme into a ready engine — the one call a\n * renderer needs. `compile` is memoized, so re-creating an engine for the same\n * config (e.g. only the theme changed) is cheap.\n */\nexport function createEngine(\n config: Config,\n theme: ResolvedTheme = \"light\",\n capabilities?: Capabilities,\n): EngineHandle {\n let compiled = compile(config);\n if (capabilities) compiled = resolveCapabilities(compiled, capabilities);\n return {\n getStateAt: createGetStateAt(compiled, theme),\n durationMs: compiled.durationMs,\n steps: compiled.stepBoundaries,\n };\n}\n","/**\n * `@typecaast/core` — the framework-agnostic engine and, locked first, the\n * contracts the rest of the system builds against: `SimState` (the renderable\n * state), the skin-prop data types, and the `Player` interface.\n *\n * The engine implementation (`compile` + `getStateAt`) lands in M1-engine,\n * behind these same contracts.\n */\n\n/** Contract version for the SimState/Player/skin-prop surface. */\nexport const CORE_CONTRACT_VERSION = 1;\n\nexport type * from \"./sim-state.js\";\nexport type * from \"./skin-props.js\";\nexport type * from \"./player.js\";\n\n/** The engine: compile() + getStateAt() + createEngine(). */\nexport * from \"./engine/index.js\";\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as ResolvedTheme, C as ComposerState, a as RenderedMessage, b as RenderedReaction, T as TypingState, M as MessageVariant, S as SystemCard, G as GetStateAt, c as SimState } from './create-player-BUru5tb_.cjs';
2
- export { d as MessageState, P as Player, e as PlayerEvent, f as PlayerEventMap, g as PlayerOptions, h as ScrollReason, i as ScrollState, j as TimelinePlayer, k as createPlayer } from './create-player-BUru5tb_.cjs';
1
+ import { R as ResolvedTheme, C as ComposerState, a as RenderedMessage, b as RenderedReaction, T as TypingState, M as MessageVariant, G as GetStateAt, S as SimState } from './create-player-DMElDIxY.cjs';
2
+ export { c as MessageState, P as Player, d as PlayerEvent, e as PlayerEventMap, f as PlayerOptions, g as ScrollReason, h as ScrollState, i as TimelinePlayer, j as createPlayer } from './create-player-DMElDIxY.cjs';
3
3
  import { Participant, ComposerMode, ContentNode, StepType, Config } from '@typecaast/schema';
4
4
 
5
5
  /**
@@ -72,7 +72,7 @@ interface CompiledReaction {
72
72
  appearMs: number;
73
73
  popMs: number;
74
74
  }
75
- /** A thread item (message or system card) with absolute timing. */
75
+ /** A thread item (message or system/notice line) with absolute timing. */
76
76
  interface CompiledMessage {
77
77
  id: string;
78
78
  from: string;
@@ -87,7 +87,6 @@ interface CompiledMessage {
87
87
  /** Display timestamp (= appearMs). */
88
88
  atMs: number;
89
89
  reactions: CompiledReaction[];
90
- system?: SystemCard;
91
90
  /** Set if an edit replaces the content at/after this time. */
92
91
  editedAtMs?: number;
93
92
  editedContent?: ContentNode[];
@@ -223,4 +222,4 @@ declare function createEngine(config: Config, theme?: ResolvedTheme, capabilitie
223
222
  /** Contract version for the SimState/Player/skin-prop surface. */
224
223
  declare const CORE_CONTRACT_VERSION = 1;
225
224
 
226
- export { type AvatarProps, CORE_CONTRACT_VERSION, type Capabilities, type CompiledComposer, type CompiledMessage, type CompiledReaction, type CompiledTimeline, type CompiledTyping, type ComposerProps, ComposerState, type EngineHandle, type EventCapability, type FrameProps, GetStateAt, type MessageProps, MessageVariant, type ReactionProps, RenderedMessage, RenderedReaction, ResolvedTheme, SimState, SystemCard, type SystemProps, type TypingProps, TypingState, compile, createEngine, createGetStateAt, createRng, graphemeCount, readingDelayMs, resolveCapabilities, sampleState, typingDurationMs, withJitter };
225
+ export { type AvatarProps, CORE_CONTRACT_VERSION, type Capabilities, type CompiledComposer, type CompiledMessage, type CompiledReaction, type CompiledTimeline, type CompiledTyping, type ComposerProps, ComposerState, type EngineHandle, type EventCapability, type FrameProps, GetStateAt, type MessageProps, MessageVariant, type ReactionProps, RenderedMessage, RenderedReaction, ResolvedTheme, SimState, type SystemProps, type TypingProps, TypingState, compile, createEngine, createGetStateAt, createRng, graphemeCount, readingDelayMs, resolveCapabilities, sampleState, typingDurationMs, withJitter };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as ResolvedTheme, C as ComposerState, a as RenderedMessage, b as RenderedReaction, T as TypingState, M as MessageVariant, S as SystemCard, G as GetStateAt, c as SimState } from './create-player-BUru5tb_.js';
2
- export { d as MessageState, P as Player, e as PlayerEvent, f as PlayerEventMap, g as PlayerOptions, h as ScrollReason, i as ScrollState, j as TimelinePlayer, k as createPlayer } from './create-player-BUru5tb_.js';
1
+ import { R as ResolvedTheme, C as ComposerState, a as RenderedMessage, b as RenderedReaction, T as TypingState, M as MessageVariant, G as GetStateAt, S as SimState } from './create-player-DMElDIxY.js';
2
+ export { c as MessageState, P as Player, d as PlayerEvent, e as PlayerEventMap, f as PlayerOptions, g as ScrollReason, h as ScrollState, i as TimelinePlayer, j as createPlayer } from './create-player-DMElDIxY.js';
3
3
  import { Participant, ComposerMode, ContentNode, StepType, Config } from '@typecaast/schema';
4
4
 
5
5
  /**
@@ -72,7 +72,7 @@ interface CompiledReaction {
72
72
  appearMs: number;
73
73
  popMs: number;
74
74
  }
75
- /** A thread item (message or system card) with absolute timing. */
75
+ /** A thread item (message or system/notice line) with absolute timing. */
76
76
  interface CompiledMessage {
77
77
  id: string;
78
78
  from: string;
@@ -87,7 +87,6 @@ interface CompiledMessage {
87
87
  /** Display timestamp (= appearMs). */
88
88
  atMs: number;
89
89
  reactions: CompiledReaction[];
90
- system?: SystemCard;
91
90
  /** Set if an edit replaces the content at/after this time. */
92
91
  editedAtMs?: number;
93
92
  editedContent?: ContentNode[];
@@ -223,4 +222,4 @@ declare function createEngine(config: Config, theme?: ResolvedTheme, capabilitie
223
222
  /** Contract version for the SimState/Player/skin-prop surface. */
224
223
  declare const CORE_CONTRACT_VERSION = 1;
225
224
 
226
- export { type AvatarProps, CORE_CONTRACT_VERSION, type Capabilities, type CompiledComposer, type CompiledMessage, type CompiledReaction, type CompiledTimeline, type CompiledTyping, type ComposerProps, ComposerState, type EngineHandle, type EventCapability, type FrameProps, GetStateAt, type MessageProps, MessageVariant, type ReactionProps, RenderedMessage, RenderedReaction, ResolvedTheme, SimState, SystemCard, type SystemProps, type TypingProps, TypingState, compile, createEngine, createGetStateAt, createRng, graphemeCount, readingDelayMs, resolveCapabilities, sampleState, typingDurationMs, withJitter };
225
+ export { type AvatarProps, CORE_CONTRACT_VERSION, type Capabilities, type CompiledComposer, type CompiledMessage, type CompiledReaction, type CompiledTimeline, type CompiledTyping, type ComposerProps, ComposerState, type EngineHandle, type EventCapability, type FrameProps, GetStateAt, type MessageProps, MessageVariant, type ReactionProps, RenderedMessage, RenderedReaction, ResolvedTheme, SimState, type SystemProps, type TypingProps, TypingState, compile, createEngine, createGetStateAt, createRng, graphemeCount, readingDelayMs, resolveCapabilities, sampleState, typingDurationMs, withJitter };