@tangle-network/agent-app 0.11.1 → 0.12.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.
@@ -0,0 +1,368 @@
1
+ import {
2
+ MIN_SEQUENCE_CLIP_FRAMES
3
+ } from "../chunk-ZYBWGSAZ.js";
4
+
5
+ // src/sequences/schema.ts
6
+ import { sql } from "drizzle-orm";
7
+ import { index, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
8
+ var hexId = () => text("id").primaryKey().default(sql`(lower(hex(randomblob(16))))`);
9
+ var jsonMetadata = () => text("metadata", { mode: "json" }).$type().default({});
10
+ var createdAt = () => integer("created_at", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`);
11
+ var updatedAt = () => integer("updated_at", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`);
12
+ function createSequenceTables(opts) {
13
+ const { workspaceTable, userTable, generationTable, assetTable } = opts;
14
+ const sequences = sqliteTable("sequence", {
15
+ id: hexId(),
16
+ workspaceId: text("workspace_id").notNull().references(() => workspaceTable.id, { onDelete: "cascade" }),
17
+ title: text("title").notNull(),
18
+ fps: integer("fps").notNull().default(30),
19
+ width: integer("width").notNull().default(1080),
20
+ height: integer("height").notNull().default(1920),
21
+ aspectRatio: text("aspect_ratio").notNull().default("9:16"),
22
+ durationFrames: integer("duration_frames").notNull().default(900),
23
+ status: text("status", { enum: ["draft", "active", "exporting", "archived"] }).notNull().default("draft"),
24
+ metadata: jsonMetadata(),
25
+ createdBy: text("created_by").notNull().references(() => userTable.id),
26
+ createdAt: createdAt(),
27
+ updatedAt: updatedAt()
28
+ }, (table) => [
29
+ index("idx_sequence_workspace_status").on(table.workspaceId, table.status),
30
+ index("idx_sequence_workspace_updated").on(table.workspaceId, table.updatedAt)
31
+ ]);
32
+ const sequenceTracks = sqliteTable("sequence_track", {
33
+ id: hexId(),
34
+ sequenceId: text("sequence_id").notNull().references(() => sequences.id, { onDelete: "cascade" }),
35
+ workspaceId: text("workspace_id").notNull().references(() => workspaceTable.id, { onDelete: "cascade" }),
36
+ kind: text("kind", { enum: ["video", "audio", "caption", "reference", "agent"] }).notNull(),
37
+ name: text("name").notNull(),
38
+ sortOrder: integer("sort_order").notNull().default(0),
39
+ locked: integer("locked", { mode: "boolean" }).notNull().default(false),
40
+ muted: integer("muted", { mode: "boolean" }).notNull().default(false),
41
+ metadata: jsonMetadata(),
42
+ createdAt: createdAt()
43
+ }, (table) => [
44
+ index("idx_sequence_track_sequence_order").on(table.sequenceId, table.sortOrder),
45
+ index("idx_sequence_track_workspace").on(table.workspaceId)
46
+ ]);
47
+ const sequenceClips = sqliteTable("sequence_clip", {
48
+ id: hexId(),
49
+ sequenceId: text("sequence_id").notNull().references(() => sequences.id, { onDelete: "cascade" }),
50
+ trackId: text("track_id").notNull().references(() => sequenceTracks.id, { onDelete: "cascade" }),
51
+ workspaceId: text("workspace_id").notNull().references(() => workspaceTable.id, { onDelete: "cascade" }),
52
+ assetId: assetTable ? text("asset_id").references(() => assetTable.id, { onDelete: "set null" }) : text("asset_id"),
53
+ generationId: generationTable ? text("generation_id").references(() => generationTable.id, { onDelete: "set null" }) : text("generation_id"),
54
+ label: text("label").notNull(),
55
+ startFrame: integer("start_frame").notNull().default(0),
56
+ durationFrames: integer("duration_frames").notNull(),
57
+ sourceInFrame: integer("source_in_frame").notNull().default(0),
58
+ sourceOutFrame: integer("source_out_frame"),
59
+ version: integer("version").notNull().default(1),
60
+ disabled: integer("disabled", { mode: "boolean" }).notNull().default(false),
61
+ text: text("text"),
62
+ language: text("language"),
63
+ metadata: jsonMetadata(),
64
+ createdBy: text("created_by").notNull().references(() => userTable.id),
65
+ createdAt: createdAt(),
66
+ updatedAt: updatedAt()
67
+ }, (table) => [
68
+ index("idx_sequence_clip_sequence_start").on(table.sequenceId, table.startFrame),
69
+ index("idx_sequence_clip_track_start").on(table.trackId, table.startFrame),
70
+ index("idx_sequence_clip_generation").on(table.generationId),
71
+ index("idx_sequence_clip_workspace").on(table.workspaceId)
72
+ ]);
73
+ const sequenceDecisions = sqliteTable("sequence_decision", {
74
+ id: hexId(),
75
+ sequenceId: text("sequence_id").notNull().references(() => sequences.id, { onDelete: "cascade" }),
76
+ clipId: text("clip_id").references(() => sequenceClips.id, { onDelete: "set null" }),
77
+ workspaceId: text("workspace_id").notNull().references(() => workspaceTable.id, { onDelete: "cascade" }),
78
+ kind: text("kind", { enum: ["human_edit", "agent_proposal", "agent_edit", "export", "note"] }).notNull(),
79
+ instruction: text("instruction").notNull(),
80
+ reasoningSummary: text("reasoning_summary"),
81
+ accepted: integer("accepted", { mode: "boolean" }),
82
+ metadata: jsonMetadata(),
83
+ createdBy: text("created_by").notNull().references(() => userTable.id),
84
+ createdAt: createdAt()
85
+ }, (table) => [
86
+ index("idx_sequence_decision_sequence").on(table.sequenceId, table.createdAt),
87
+ index("idx_sequence_decision_workspace").on(table.workspaceId)
88
+ ]);
89
+ const sequenceExports = sqliteTable("sequence_export", {
90
+ id: hexId(),
91
+ workspaceId: text("workspace_id").notNull().references(() => workspaceTable.id, { onDelete: "cascade" }),
92
+ sequenceId: text("sequence_id").notNull().references(() => sequences.id, { onDelete: "cascade" }),
93
+ format: text("format", { enum: ["mp4", "otio", "xml", "edl", "vtt", "srt", "contact_sheet"] }).notNull(),
94
+ status: text("status", { enum: ["queued", "processing", "completed", "failed", "cancelled"] }).notNull().default("queued"),
95
+ resultUrl: text("result_url"),
96
+ metadata: jsonMetadata(),
97
+ createdBy: text("created_by").notNull().references(() => userTable.id),
98
+ createdAt: createdAt(),
99
+ completedAt: integer("completed_at", { mode: "timestamp" })
100
+ }, (table) => [
101
+ index("idx_sequence_export_sequence").on(table.sequenceId, table.createdAt),
102
+ index("idx_sequence_export_workspace_status").on(table.workspaceId, table.status)
103
+ ]);
104
+ return { sequences, sequenceTracks, sequenceClips, sequenceDecisions, sequenceExports };
105
+ }
106
+
107
+ // src/sequences/drizzle-store.ts
108
+ import { and, asc, desc, eq, sql as sql2 } from "drizzle-orm";
109
+ var DEFAULT_LIST_LIMIT = 50;
110
+ function createDrizzleSequenceStore(options) {
111
+ const { db, tables, scope, resolveMedia } = options;
112
+ const { sequences, sequenceTracks, sequenceClips, sequenceDecisions, sequenceExports } = tables;
113
+ const sequenceScope = () => and(eq(sequences.id, scope.sequenceId), eq(sequences.workspaceId, scope.workspaceId));
114
+ const trackScope = () => and(eq(sequenceTracks.sequenceId, scope.sequenceId), eq(sequenceTracks.workspaceId, scope.workspaceId));
115
+ const clipScope = () => and(eq(sequenceClips.sequenceId, scope.sequenceId), eq(sequenceClips.workspaceId, scope.workspaceId));
116
+ const decisionScope = () => and(eq(sequenceDecisions.sequenceId, scope.sequenceId), eq(sequenceDecisions.workspaceId, scope.workspaceId));
117
+ const exportScope = () => and(eq(sequenceExports.sequenceId, scope.sequenceId), eq(sequenceExports.workspaceId, scope.workspaceId));
118
+ async function requireSequenceRow() {
119
+ const [row] = await db.select().from(sequences).where(sequenceScope()).limit(1);
120
+ if (!row) throw new Error(`Sequence ${scope.sequenceId} not found in workspace ${scope.workspaceId}`);
121
+ return row;
122
+ }
123
+ async function requireTrackRow(trackId) {
124
+ const [row] = await db.select().from(sequenceTracks).where(and(trackScope(), eq(sequenceTracks.id, trackId))).limit(1);
125
+ if (!row) throw new Error(`Track ${trackId} not found in sequence ${scope.sequenceId}`);
126
+ return row;
127
+ }
128
+ async function requireClipRow(clipId) {
129
+ const [row] = await db.select().from(sequenceClips).where(and(clipScope(), eq(sequenceClips.id, clipId))).limit(1);
130
+ if (!row) throw new Error(`Clip ${clipId} not found in sequence ${scope.sequenceId}`);
131
+ return row;
132
+ }
133
+ async function touchSequence() {
134
+ await db.update(sequences).set({ updatedAt: /* @__PURE__ */ new Date() }).where(sequenceScope());
135
+ }
136
+ async function clipWithMedia(row) {
137
+ const media = resolveMedia ? await resolveMedia([row]) : void 0;
138
+ return mapClip(row, media?.get(row.id));
139
+ }
140
+ return {
141
+ async getTimeline() {
142
+ const sequenceRow = await requireSequenceRow();
143
+ const [trackRows, clipRows] = await Promise.all([
144
+ db.select().from(sequenceTracks).where(trackScope()).orderBy(asc(sequenceTracks.sortOrder), asc(sequenceTracks.createdAt)),
145
+ db.select().from(sequenceClips).where(clipScope()).orderBy(asc(sequenceClips.startFrame), asc(sequenceClips.createdAt))
146
+ ]);
147
+ const media = resolveMedia ? await resolveMedia(clipRows) : void 0;
148
+ return {
149
+ sequence: mapSequence(sequenceRow),
150
+ tracks: trackRows.map(mapTrack),
151
+ clips: clipRows.map((row) => mapClip(row, media?.get(row.id)))
152
+ };
153
+ },
154
+ async getClip(clipId) {
155
+ return clipWithMedia(await requireClipRow(clipId));
156
+ },
157
+ async createTrack(input) {
158
+ await requireSequenceRow();
159
+ let sortOrder = input.sortOrder;
160
+ if (sortOrder === void 0) {
161
+ const [aggregate] = await db.select({ maxSortOrder: sql2`max(${sequenceTracks.sortOrder})` }).from(sequenceTracks).where(trackScope());
162
+ sortOrder = (aggregate?.maxSortOrder ?? -1) + 1;
163
+ }
164
+ const [row] = await db.insert(sequenceTracks).values({
165
+ sequenceId: scope.sequenceId,
166
+ workspaceId: scope.workspaceId,
167
+ kind: input.kind,
168
+ name: input.name,
169
+ sortOrder
170
+ }).returning();
171
+ if (!row) throw new Error("sequence_track insert returned no row");
172
+ await touchSequence();
173
+ return mapTrack(row);
174
+ },
175
+ async createClip(input) {
176
+ assertFrame(input.startFrame, "startFrame");
177
+ assertClipDuration(input.durationFrames);
178
+ if (input.sourceInFrame !== void 0) assertFrame(input.sourceInFrame, "sourceInFrame");
179
+ if (typeof input.sourceOutFrame === "number") assertFrame(input.sourceOutFrame, "sourceOutFrame");
180
+ await requireTrackRow(input.trackId);
181
+ const [row] = await db.insert(sequenceClips).values({
182
+ sequenceId: scope.sequenceId,
183
+ workspaceId: scope.workspaceId,
184
+ trackId: input.trackId,
185
+ label: input.label,
186
+ startFrame: input.startFrame,
187
+ durationFrames: input.durationFrames,
188
+ sourceInFrame: input.sourceInFrame ?? 0,
189
+ sourceOutFrame: input.sourceOutFrame ?? null,
190
+ text: input.text ?? null,
191
+ language: input.language ?? null,
192
+ generationId: input.generationId ?? null,
193
+ assetId: input.assetId ?? null,
194
+ metadata: input.metadata ?? {},
195
+ createdBy: scope.userId
196
+ }).returning();
197
+ if (!row) throw new Error("sequence_clip insert returned no row");
198
+ await touchSequence();
199
+ return clipWithMedia(row);
200
+ },
201
+ async updateClip(clipId, patch) {
202
+ await requireClipRow(clipId);
203
+ if (patch.trackId !== void 0) await requireTrackRow(patch.trackId);
204
+ if (patch.startFrame !== void 0) assertFrame(patch.startFrame, "startFrame");
205
+ if (patch.durationFrames !== void 0) assertClipDuration(patch.durationFrames);
206
+ if (patch.sourceInFrame !== void 0) assertFrame(patch.sourceInFrame, "sourceInFrame");
207
+ if (typeof patch.sourceOutFrame === "number") assertFrame(patch.sourceOutFrame, "sourceOutFrame");
208
+ const updates = {
209
+ updatedAt: /* @__PURE__ */ new Date(),
210
+ version: sql2`${sequenceClips.version} + 1`
211
+ };
212
+ if (patch.trackId !== void 0) updates.trackId = patch.trackId;
213
+ if (patch.label !== void 0) updates.label = patch.label;
214
+ if (patch.startFrame !== void 0) updates.startFrame = patch.startFrame;
215
+ if (patch.durationFrames !== void 0) updates.durationFrames = patch.durationFrames;
216
+ if (patch.sourceInFrame !== void 0) updates.sourceInFrame = patch.sourceInFrame;
217
+ if (patch.sourceOutFrame !== void 0) updates.sourceOutFrame = patch.sourceOutFrame;
218
+ if (patch.disabled !== void 0) updates.disabled = patch.disabled;
219
+ if (patch.text !== void 0) updates.text = patch.text;
220
+ if (patch.language !== void 0) updates.language = patch.language;
221
+ if (patch.metadata !== void 0) updates.metadata = patch.metadata;
222
+ const [row] = await db.update(sequenceClips).set(updates).where(and(clipScope(), eq(sequenceClips.id, clipId))).returning();
223
+ if (!row) throw new Error(`Clip ${clipId} not found in sequence ${scope.sequenceId}`);
224
+ await touchSequence();
225
+ return clipWithMedia(row);
226
+ },
227
+ async deleteClip(clipId) {
228
+ await requireClipRow(clipId);
229
+ await db.delete(sequenceClips).where(and(clipScope(), eq(sequenceClips.id, clipId)));
230
+ await touchSequence();
231
+ },
232
+ async updateSequenceDuration(durationFrames) {
233
+ if (!Number.isInteger(durationFrames) || durationFrames < MIN_SEQUENCE_CLIP_FRAMES) {
234
+ throw new Error("durationFrames must be a positive integer");
235
+ }
236
+ await requireSequenceRow();
237
+ const [aggregate] = await db.select({ maxEndFrame: sql2`max(${sequenceClips.startFrame} + ${sequenceClips.durationFrames})` }).from(sequenceClips).where(clipScope());
238
+ const maxEndFrame = aggregate?.maxEndFrame ?? 0;
239
+ if (durationFrames < maxEndFrame) {
240
+ throw new Error(`Cannot set sequence duration to ${durationFrames} frames: the last clip ends at frame ${maxEndFrame}. Trim or delete clips first.`);
241
+ }
242
+ const [row] = await db.update(sequences).set({ durationFrames, updatedAt: /* @__PURE__ */ new Date() }).where(sequenceScope()).returning();
243
+ if (!row) throw new Error(`Sequence ${scope.sequenceId} not found in workspace ${scope.workspaceId}`);
244
+ return mapSequence(row);
245
+ },
246
+ async recordDecision(input) {
247
+ await requireSequenceRow();
248
+ if (typeof input.clipId === "string") await requireClipRow(input.clipId);
249
+ const [row] = await db.insert(sequenceDecisions).values({
250
+ sequenceId: scope.sequenceId,
251
+ workspaceId: scope.workspaceId,
252
+ clipId: input.clipId ?? null,
253
+ kind: input.kind,
254
+ instruction: input.instruction,
255
+ reasoningSummary: input.reasoningSummary ?? null,
256
+ accepted: input.accepted ?? null,
257
+ metadata: input.metadata ?? {},
258
+ createdBy: scope.userId
259
+ }).returning();
260
+ if (!row) throw new Error("sequence_decision insert returned no row");
261
+ await touchSequence();
262
+ return mapDecision(row);
263
+ },
264
+ async createExport(format, metadata) {
265
+ await requireSequenceRow();
266
+ const [row] = await db.insert(sequenceExports).values({
267
+ sequenceId: scope.sequenceId,
268
+ workspaceId: scope.workspaceId,
269
+ format,
270
+ metadata: metadata ?? {},
271
+ createdBy: scope.userId
272
+ }).returning();
273
+ if (!row) throw new Error("sequence_export insert returned no row");
274
+ await touchSequence();
275
+ return mapExport(row);
276
+ },
277
+ async listDecisions(limit = DEFAULT_LIST_LIMIT) {
278
+ assertListLimit(limit);
279
+ const rows = await db.select().from(sequenceDecisions).where(decisionScope()).orderBy(desc(sequenceDecisions.createdAt), desc(sql2`rowid`)).limit(limit);
280
+ return rows.map(mapDecision);
281
+ },
282
+ async listExports(limit = DEFAULT_LIST_LIMIT) {
283
+ assertListLimit(limit);
284
+ const rows = await db.select().from(sequenceExports).where(exportScope()).orderBy(desc(sequenceExports.createdAt), desc(sql2`rowid`)).limit(limit);
285
+ return rows.map(mapExport);
286
+ }
287
+ };
288
+ }
289
+ function mapSequence(row) {
290
+ return {
291
+ id: row.id,
292
+ title: row.title,
293
+ fps: row.fps,
294
+ width: row.width,
295
+ height: row.height,
296
+ aspectRatio: row.aspectRatio,
297
+ durationFrames: row.durationFrames,
298
+ status: row.status,
299
+ metadata: row.metadata ?? {}
300
+ };
301
+ }
302
+ function mapTrack(row) {
303
+ return {
304
+ id: row.id,
305
+ kind: row.kind,
306
+ name: row.name,
307
+ sortOrder: row.sortOrder,
308
+ locked: row.locked,
309
+ muted: row.muted,
310
+ metadata: row.metadata ?? {}
311
+ };
312
+ }
313
+ function mapClip(row, media) {
314
+ return {
315
+ id: row.id,
316
+ trackId: row.trackId,
317
+ label: row.label,
318
+ startFrame: row.startFrame,
319
+ durationFrames: row.durationFrames,
320
+ sourceInFrame: row.sourceInFrame,
321
+ sourceOutFrame: row.sourceOutFrame,
322
+ disabled: row.disabled,
323
+ text: row.text ?? void 0,
324
+ language: row.language ?? void 0,
325
+ generationId: row.generationId ?? void 0,
326
+ assetId: row.assetId ?? void 0,
327
+ media,
328
+ metadata: row.metadata ?? {}
329
+ };
330
+ }
331
+ function mapDecision(row) {
332
+ return {
333
+ id: row.id,
334
+ clipId: row.clipId,
335
+ kind: row.kind,
336
+ instruction: row.instruction,
337
+ reasoningSummary: row.reasoningSummary,
338
+ accepted: row.accepted,
339
+ metadata: row.metadata ?? {},
340
+ createdAt: row.createdAt
341
+ };
342
+ }
343
+ function mapExport(row) {
344
+ return {
345
+ id: row.id,
346
+ format: row.format,
347
+ status: row.status,
348
+ resultUrl: row.resultUrl,
349
+ metadata: row.metadata ?? {},
350
+ createdAt: row.createdAt
351
+ };
352
+ }
353
+ function assertFrame(value, label) {
354
+ if (!Number.isInteger(value) || value < 0) throw new Error(`${label} must be a non-negative integer`);
355
+ }
356
+ function assertClipDuration(durationFrames) {
357
+ if (!Number.isInteger(durationFrames) || durationFrames < MIN_SEQUENCE_CLIP_FRAMES) {
358
+ throw new Error("durationFrames must be a positive integer");
359
+ }
360
+ }
361
+ function assertListLimit(limit) {
362
+ if (!Number.isInteger(limit) || limit < 1) throw new Error("limit must be a positive integer");
363
+ }
364
+ export {
365
+ createDrizzleSequenceStore,
366
+ createSequenceTables
367
+ };
368
+ //# sourceMappingURL=drizzle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/sequences/schema.ts","../../src/sequences/drizzle-store.ts"],"sourcesContent":["/**\n * Drizzle schema factory for the sequence tables. The product owns the\n * workspace/user (and optionally generation/asset) tables; the factory wires\n * the sequence tables' foreign keys into them so the whole graph lives in one\n * drizzle schema with real cascade semantics. Column names, types, defaults,\n * enums, and indexes mirror creative-agent's hand-rolled tables so a product\n * with those tables can adopt the factory without rewriting rows.\n *\n * `sequence_clip.text` / `sequence_clip.language` hold caption bodies inline\n * (nullable; only caption-track clips use them) — adopting products add the\n * two columns with a plain ALTER TABLE.\n *\n * When `generationTable`/`assetTable` are omitted the `generation_id` /\n * `asset_id` columns stay plain text (no FK): products without those tables\n * still get opaque reference columns the store round-trips untouched.\n */\n\nimport { sql } from 'drizzle-orm'\nimport { index, integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'\nimport type { AnySQLiteColumn, AnySQLiteTable } from 'drizzle-orm/sqlite-core'\n\n/** A product table referenced by FK — only the `id` column is touched. */\nexport type SequenceParentTable = AnySQLiteTable & { id: AnySQLiteColumn }\n\nexport interface CreateSequenceTablesOptions {\n workspaceTable: SequenceParentTable\n userTable: SequenceParentTable\n generationTable?: SequenceParentTable\n assetTable?: SequenceParentTable\n}\n\nconst hexId = () => text('id').primaryKey().default(sql`(lower(hex(randomblob(16))))`)\n\nconst jsonMetadata = () => text('metadata', { mode: 'json' }).$type<Record<string, unknown>>().default({})\n\nconst createdAt = () => integer('created_at', { mode: 'timestamp' }).notNull().default(sql`(unixepoch())`)\n\nconst updatedAt = () => integer('updated_at', { mode: 'timestamp' }).notNull().default(sql`(unixepoch())`)\n\nexport function createSequenceTables(opts: CreateSequenceTablesOptions) {\n const { workspaceTable, userTable, generationTable, assetTable } = opts\n\n const sequences = sqliteTable('sequence', {\n id: hexId(),\n workspaceId: text('workspace_id').notNull().references(() => workspaceTable.id, { onDelete: 'cascade' }),\n title: text('title').notNull(),\n fps: integer('fps').notNull().default(30),\n width: integer('width').notNull().default(1080),\n height: integer('height').notNull().default(1920),\n aspectRatio: text('aspect_ratio').notNull().default('9:16'),\n durationFrames: integer('duration_frames').notNull().default(900),\n status: text('status', { enum: ['draft', 'active', 'exporting', 'archived'] }).notNull().default('draft'),\n metadata: jsonMetadata(),\n createdBy: text('created_by').notNull().references(() => userTable.id),\n createdAt: createdAt(),\n updatedAt: updatedAt(),\n }, (table) => [\n index('idx_sequence_workspace_status').on(table.workspaceId, table.status),\n index('idx_sequence_workspace_updated').on(table.workspaceId, table.updatedAt),\n ])\n\n const sequenceTracks = sqliteTable('sequence_track', {\n id: hexId(),\n sequenceId: text('sequence_id').notNull().references(() => sequences.id, { onDelete: 'cascade' }),\n workspaceId: text('workspace_id').notNull().references(() => workspaceTable.id, { onDelete: 'cascade' }),\n kind: text('kind', { enum: ['video', 'audio', 'caption', 'reference', 'agent'] }).notNull(),\n name: text('name').notNull(),\n sortOrder: integer('sort_order').notNull().default(0),\n locked: integer('locked', { mode: 'boolean' }).notNull().default(false),\n muted: integer('muted', { mode: 'boolean' }).notNull().default(false),\n metadata: jsonMetadata(),\n createdAt: createdAt(),\n }, (table) => [\n index('idx_sequence_track_sequence_order').on(table.sequenceId, table.sortOrder),\n index('idx_sequence_track_workspace').on(table.workspaceId),\n ])\n\n const sequenceClips = sqliteTable('sequence_clip', {\n id: hexId(),\n sequenceId: text('sequence_id').notNull().references(() => sequences.id, { onDelete: 'cascade' }),\n trackId: text('track_id').notNull().references(() => sequenceTracks.id, { onDelete: 'cascade' }),\n workspaceId: text('workspace_id').notNull().references(() => workspaceTable.id, { onDelete: 'cascade' }),\n assetId: assetTable\n ? text('asset_id').references(() => assetTable.id, { onDelete: 'set null' })\n : text('asset_id'),\n generationId: generationTable\n ? text('generation_id').references(() => generationTable.id, { onDelete: 'set null' })\n : text('generation_id'),\n label: text('label').notNull(),\n startFrame: integer('start_frame').notNull().default(0),\n durationFrames: integer('duration_frames').notNull(),\n sourceInFrame: integer('source_in_frame').notNull().default(0),\n sourceOutFrame: integer('source_out_frame'),\n version: integer('version').notNull().default(1),\n disabled: integer('disabled', { mode: 'boolean' }).notNull().default(false),\n text: text('text'),\n language: text('language'),\n metadata: jsonMetadata(),\n createdBy: text('created_by').notNull().references(() => userTable.id),\n createdAt: createdAt(),\n updatedAt: updatedAt(),\n }, (table) => [\n index('idx_sequence_clip_sequence_start').on(table.sequenceId, table.startFrame),\n index('idx_sequence_clip_track_start').on(table.trackId, table.startFrame),\n index('idx_sequence_clip_generation').on(table.generationId),\n index('idx_sequence_clip_workspace').on(table.workspaceId),\n ])\n\n const sequenceDecisions = sqliteTable('sequence_decision', {\n id: hexId(),\n sequenceId: text('sequence_id').notNull().references(() => sequences.id, { onDelete: 'cascade' }),\n clipId: text('clip_id').references(() => sequenceClips.id, { onDelete: 'set null' }),\n workspaceId: text('workspace_id').notNull().references(() => workspaceTable.id, { onDelete: 'cascade' }),\n kind: text('kind', { enum: ['human_edit', 'agent_proposal', 'agent_edit', 'export', 'note'] }).notNull(),\n instruction: text('instruction').notNull(),\n reasoningSummary: text('reasoning_summary'),\n accepted: integer('accepted', { mode: 'boolean' }),\n metadata: jsonMetadata(),\n createdBy: text('created_by').notNull().references(() => userTable.id),\n createdAt: createdAt(),\n }, (table) => [\n index('idx_sequence_decision_sequence').on(table.sequenceId, table.createdAt),\n index('idx_sequence_decision_workspace').on(table.workspaceId),\n ])\n\n const sequenceExports = sqliteTable('sequence_export', {\n id: hexId(),\n workspaceId: text('workspace_id').notNull().references(() => workspaceTable.id, { onDelete: 'cascade' }),\n sequenceId: text('sequence_id').notNull().references(() => sequences.id, { onDelete: 'cascade' }),\n format: text('format', { enum: ['mp4', 'otio', 'xml', 'edl', 'vtt', 'srt', 'contact_sheet'] }).notNull(),\n status: text('status', { enum: ['queued', 'processing', 'completed', 'failed', 'cancelled'] }).notNull().default('queued'),\n resultUrl: text('result_url'),\n metadata: jsonMetadata(),\n createdBy: text('created_by').notNull().references(() => userTable.id),\n createdAt: createdAt(),\n completedAt: integer('completed_at', { mode: 'timestamp' }),\n }, (table) => [\n index('idx_sequence_export_sequence').on(table.sequenceId, table.createdAt),\n index('idx_sequence_export_workspace_status').on(table.workspaceId, table.status),\n ])\n\n return { sequences, sequenceTracks, sequenceClips, sequenceDecisions, sequenceExports }\n}\n\nexport type SequenceTables = ReturnType<typeof createSequenceTables>\n\nexport type SequenceRow = SequenceTables['sequences']['$inferSelect']\nexport type SequenceTrackRow = SequenceTables['sequenceTracks']['$inferSelect']\nexport type SequenceClipRow = SequenceTables['sequenceClips']['$inferSelect']\nexport type SequenceDecisionRow = SequenceTables['sequenceDecisions']['$inferSelect']\nexport type SequenceExportRow = SequenceTables['sequenceExports']['$inferSelect']\n","/**\n * Drizzle-backed `SequenceStore` over the tables from `createSequenceTables`.\n * Works against any SQLite drizzle driver (better-sqlite3, D1, libsql) — the\n * builders are awaited, never `.run()`/`.all()`, so sync and async drivers\n * behave identically.\n *\n * Defense in depth: RBAC runs before the store is constructed, but every\n * query still pins `workspaceId` AND `sequenceId` from the scope in its WHERE\n * clause, so a leaked or attacker-supplied row id from another workspace can\n * never read or write across the boundary — it surfaces as \"not found\".\n *\n * Store-level invariants (everything richer lives in the operation\n * validator): frame fields must be non-negative integers, clip durations at\n * least `MIN_SEQUENCE_CLIP_FRAMES`, and the sequence duration can never\n * shrink below the last clip end. Every mutation bumps `sequence.updatedAt`\n * so workspace recency sorts stay truthful.\n */\n\nimport { and, asc, desc, eq, sql } from 'drizzle-orm'\nimport type { BaseSQLiteDatabase, SQLiteUpdateSetSource } from 'drizzle-orm/sqlite-core'\nimport {\n MIN_SEQUENCE_CLIP_FRAMES,\n type SequenceClip,\n type SequenceClipMedia,\n type SequenceDecision,\n type SequenceExportFormat,\n type SequenceExportRecord,\n type SequenceMeta,\n type SequenceTimeline,\n type SequenceTrack,\n} from './model'\nimport type {\n NewSequenceClip,\n NewSequenceDecision,\n NewSequenceTrack,\n SequenceClipPatch,\n SequenceStore,\n SequenceStoreScope,\n} from './store'\nimport type {\n SequenceClipRow,\n SequenceDecisionRow,\n SequenceExportRow,\n SequenceRow,\n SequenceTables,\n SequenceTrackRow,\n} from './schema'\n\n/** Any SQLite drizzle database — `any` erases the driver-specific run-result\n * and schema generics so better-sqlite3, D1, and libsql handles all fit. */\nexport type SequenceDatabase = BaseSQLiteDatabase<'sync' | 'async', any, any>\n\n/** Resolves product-specific media (generation rows, asset rows) for a batch\n * of clip rows. Keyed by clip id; clips absent from the map carry no media. */\nexport type SequenceMediaResolver = (clipRows: SequenceClipRow[]) => Promise<Map<string, SequenceClipMedia>>\n\nexport interface CreateDrizzleSequenceStoreOptions {\n db: SequenceDatabase\n tables: SequenceTables\n scope: SequenceStoreScope\n resolveMedia?: SequenceMediaResolver\n}\n\nconst DEFAULT_LIST_LIMIT = 50\n\nexport function createDrizzleSequenceStore(options: CreateDrizzleSequenceStoreOptions): SequenceStore {\n const { db, tables, scope, resolveMedia } = options\n const { sequences, sequenceTracks, sequenceClips, sequenceDecisions, sequenceExports } = tables\n\n const sequenceScope = () => and(eq(sequences.id, scope.sequenceId), eq(sequences.workspaceId, scope.workspaceId))\n const trackScope = () => and(eq(sequenceTracks.sequenceId, scope.sequenceId), eq(sequenceTracks.workspaceId, scope.workspaceId))\n const clipScope = () => and(eq(sequenceClips.sequenceId, scope.sequenceId), eq(sequenceClips.workspaceId, scope.workspaceId))\n const decisionScope = () => and(eq(sequenceDecisions.sequenceId, scope.sequenceId), eq(sequenceDecisions.workspaceId, scope.workspaceId))\n const exportScope = () => and(eq(sequenceExports.sequenceId, scope.sequenceId), eq(sequenceExports.workspaceId, scope.workspaceId))\n\n async function requireSequenceRow(): Promise<SequenceRow> {\n const [row] = await db.select().from(sequences).where(sequenceScope()).limit(1)\n if (!row) throw new Error(`Sequence ${scope.sequenceId} not found in workspace ${scope.workspaceId}`)\n return row\n }\n\n async function requireTrackRow(trackId: string): Promise<SequenceTrackRow> {\n const [row] = await db.select().from(sequenceTracks).where(and(trackScope(), eq(sequenceTracks.id, trackId))).limit(1)\n if (!row) throw new Error(`Track ${trackId} not found in sequence ${scope.sequenceId}`)\n return row\n }\n\n async function requireClipRow(clipId: string): Promise<SequenceClipRow> {\n const [row] = await db.select().from(sequenceClips).where(and(clipScope(), eq(sequenceClips.id, clipId))).limit(1)\n if (!row) throw new Error(`Clip ${clipId} not found in sequence ${scope.sequenceId}`)\n return row\n }\n\n async function touchSequence(): Promise<void> {\n await db.update(sequences).set({ updatedAt: new Date() }).where(sequenceScope())\n }\n\n async function clipWithMedia(row: SequenceClipRow): Promise<SequenceClip> {\n const media = resolveMedia ? await resolveMedia([row]) : undefined\n return mapClip(row, media?.get(row.id))\n }\n\n return {\n async getTimeline(): Promise<SequenceTimeline> {\n const sequenceRow = await requireSequenceRow()\n const [trackRows, clipRows] = await Promise.all([\n db.select().from(sequenceTracks).where(trackScope())\n .orderBy(asc(sequenceTracks.sortOrder), asc(sequenceTracks.createdAt)),\n db.select().from(sequenceClips).where(clipScope())\n .orderBy(asc(sequenceClips.startFrame), asc(sequenceClips.createdAt)),\n ])\n const media = resolveMedia ? await resolveMedia(clipRows) : undefined\n return {\n sequence: mapSequence(sequenceRow),\n tracks: trackRows.map(mapTrack),\n clips: clipRows.map((row) => mapClip(row, media?.get(row.id))),\n }\n },\n\n async getClip(clipId: string): Promise<SequenceClip> {\n return clipWithMedia(await requireClipRow(clipId))\n },\n\n async createTrack(input: NewSequenceTrack): Promise<SequenceTrack> {\n await requireSequenceRow()\n let sortOrder = input.sortOrder\n if (sortOrder === undefined) {\n const [aggregate] = await db\n .select({ maxSortOrder: sql<number | null>`max(${sequenceTracks.sortOrder})` })\n .from(sequenceTracks)\n .where(trackScope())\n sortOrder = (aggregate?.maxSortOrder ?? -1) + 1\n }\n const [row] = await db.insert(sequenceTracks).values({\n sequenceId: scope.sequenceId,\n workspaceId: scope.workspaceId,\n kind: input.kind,\n name: input.name,\n sortOrder,\n }).returning()\n if (!row) throw new Error('sequence_track insert returned no row')\n await touchSequence()\n return mapTrack(row)\n },\n\n async createClip(input: NewSequenceClip): Promise<SequenceClip> {\n assertFrame(input.startFrame, 'startFrame')\n assertClipDuration(input.durationFrames)\n if (input.sourceInFrame !== undefined) assertFrame(input.sourceInFrame, 'sourceInFrame')\n if (typeof input.sourceOutFrame === 'number') assertFrame(input.sourceOutFrame, 'sourceOutFrame')\n await requireTrackRow(input.trackId)\n const [row] = await db.insert(sequenceClips).values({\n sequenceId: scope.sequenceId,\n workspaceId: scope.workspaceId,\n trackId: input.trackId,\n label: input.label,\n startFrame: input.startFrame,\n durationFrames: input.durationFrames,\n sourceInFrame: input.sourceInFrame ?? 0,\n sourceOutFrame: input.sourceOutFrame ?? null,\n text: input.text ?? null,\n language: input.language ?? null,\n generationId: input.generationId ?? null,\n assetId: input.assetId ?? null,\n metadata: input.metadata ?? {},\n createdBy: scope.userId,\n }).returning()\n if (!row) throw new Error('sequence_clip insert returned no row')\n await touchSequence()\n return clipWithMedia(row)\n },\n\n async updateClip(clipId: string, patch: SequenceClipPatch): Promise<SequenceClip> {\n await requireClipRow(clipId)\n if (patch.trackId !== undefined) await requireTrackRow(patch.trackId)\n if (patch.startFrame !== undefined) assertFrame(patch.startFrame, 'startFrame')\n if (patch.durationFrames !== undefined) assertClipDuration(patch.durationFrames)\n if (patch.sourceInFrame !== undefined) assertFrame(patch.sourceInFrame, 'sourceInFrame')\n if (typeof patch.sourceOutFrame === 'number') assertFrame(patch.sourceOutFrame, 'sourceOutFrame')\n\n const updates: SQLiteUpdateSetSource<SequenceTables['sequenceClips']> = {\n updatedAt: new Date(),\n version: sql`${sequenceClips.version} + 1`,\n }\n if (patch.trackId !== undefined) updates.trackId = patch.trackId\n if (patch.label !== undefined) updates.label = patch.label\n if (patch.startFrame !== undefined) updates.startFrame = patch.startFrame\n if (patch.durationFrames !== undefined) updates.durationFrames = patch.durationFrames\n if (patch.sourceInFrame !== undefined) updates.sourceInFrame = patch.sourceInFrame\n if (patch.sourceOutFrame !== undefined) updates.sourceOutFrame = patch.sourceOutFrame\n if (patch.disabled !== undefined) updates.disabled = patch.disabled\n if (patch.text !== undefined) updates.text = patch.text\n if (patch.language !== undefined) updates.language = patch.language\n if (patch.metadata !== undefined) updates.metadata = patch.metadata\n\n const [row] = await db.update(sequenceClips).set(updates)\n .where(and(clipScope(), eq(sequenceClips.id, clipId)))\n .returning()\n if (!row) throw new Error(`Clip ${clipId} not found in sequence ${scope.sequenceId}`)\n await touchSequence()\n return clipWithMedia(row)\n },\n\n async deleteClip(clipId: string): Promise<void> {\n await requireClipRow(clipId)\n await db.delete(sequenceClips).where(and(clipScope(), eq(sequenceClips.id, clipId)))\n await touchSequence()\n },\n\n async updateSequenceDuration(durationFrames: number): Promise<SequenceMeta> {\n if (!Number.isInteger(durationFrames) || durationFrames < MIN_SEQUENCE_CLIP_FRAMES) {\n throw new Error('durationFrames must be a positive integer')\n }\n await requireSequenceRow()\n // Disabled clips still occupy the timeline (they can be re-enabled), so\n // they count toward the shrink floor.\n const [aggregate] = await db\n .select({ maxEndFrame: sql<number | null>`max(${sequenceClips.startFrame} + ${sequenceClips.durationFrames})` })\n .from(sequenceClips)\n .where(clipScope())\n const maxEndFrame = aggregate?.maxEndFrame ?? 0\n if (durationFrames < maxEndFrame) {\n throw new Error(`Cannot set sequence duration to ${durationFrames} frames: the last clip ends at frame ${maxEndFrame}. Trim or delete clips first.`)\n }\n const [row] = await db.update(sequences)\n .set({ durationFrames, updatedAt: new Date() })\n .where(sequenceScope())\n .returning()\n if (!row) throw new Error(`Sequence ${scope.sequenceId} not found in workspace ${scope.workspaceId}`)\n return mapSequence(row)\n },\n\n async recordDecision(input: NewSequenceDecision): Promise<SequenceDecision> {\n await requireSequenceRow()\n if (typeof input.clipId === 'string') await requireClipRow(input.clipId)\n const [row] = await db.insert(sequenceDecisions).values({\n sequenceId: scope.sequenceId,\n workspaceId: scope.workspaceId,\n clipId: input.clipId ?? null,\n kind: input.kind,\n instruction: input.instruction,\n reasoningSummary: input.reasoningSummary ?? null,\n accepted: input.accepted ?? null,\n metadata: input.metadata ?? {},\n createdBy: scope.userId,\n }).returning()\n if (!row) throw new Error('sequence_decision insert returned no row')\n await touchSequence()\n return mapDecision(row)\n },\n\n async createExport(format: SequenceExportFormat, metadata?: Record<string, unknown>): Promise<SequenceExportRecord> {\n await requireSequenceRow()\n const [row] = await db.insert(sequenceExports).values({\n sequenceId: scope.sequenceId,\n workspaceId: scope.workspaceId,\n format,\n metadata: metadata ?? {},\n createdBy: scope.userId,\n }).returning()\n if (!row) throw new Error('sequence_export insert returned no row')\n await touchSequence()\n return mapExport(row)\n },\n\n async listDecisions(limit = DEFAULT_LIST_LIMIT): Promise<SequenceDecision[]> {\n assertListLimit(limit)\n // created_at has one-second resolution (unixepoch); rowid breaks ties in\n // insertion order so the log reads newest-first deterministically.\n const rows = await db.select().from(sequenceDecisions)\n .where(decisionScope())\n .orderBy(desc(sequenceDecisions.createdAt), desc(sql`rowid`))\n .limit(limit)\n return rows.map(mapDecision)\n },\n\n async listExports(limit = DEFAULT_LIST_LIMIT): Promise<SequenceExportRecord[]> {\n assertListLimit(limit)\n const rows = await db.select().from(sequenceExports)\n .where(exportScope())\n .orderBy(desc(sequenceExports.createdAt), desc(sql`rowid`))\n .limit(limit)\n return rows.map(mapExport)\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Row → model mapping. Metadata columns are nullable with a `{}` default;\n// SQL NULL and `{}` both mean \"no metadata\", so `?? {}` is a lossless\n// representation conversion, not an error-hiding fallback. Nullable text\n// columns map to the model's optional (`undefined`) fields the same way.\n// ---------------------------------------------------------------------------\n\nfunction mapSequence(row: SequenceRow): SequenceMeta {\n return {\n id: row.id,\n title: row.title,\n fps: row.fps,\n width: row.width,\n height: row.height,\n aspectRatio: row.aspectRatio,\n durationFrames: row.durationFrames,\n status: row.status,\n metadata: row.metadata ?? {},\n }\n}\n\nfunction mapTrack(row: SequenceTrackRow): SequenceTrack {\n return {\n id: row.id,\n kind: row.kind,\n name: row.name,\n sortOrder: row.sortOrder,\n locked: row.locked,\n muted: row.muted,\n metadata: row.metadata ?? {},\n }\n}\n\nfunction mapClip(row: SequenceClipRow, media: SequenceClipMedia | undefined): SequenceClip {\n return {\n id: row.id,\n trackId: row.trackId,\n label: row.label,\n startFrame: row.startFrame,\n durationFrames: row.durationFrames,\n sourceInFrame: row.sourceInFrame,\n sourceOutFrame: row.sourceOutFrame,\n disabled: row.disabled,\n text: row.text ?? undefined,\n language: row.language ?? undefined,\n generationId: row.generationId ?? undefined,\n assetId: row.assetId ?? undefined,\n media,\n metadata: row.metadata ?? {},\n }\n}\n\nfunction mapDecision(row: SequenceDecisionRow): SequenceDecision {\n return {\n id: row.id,\n clipId: row.clipId,\n kind: row.kind,\n instruction: row.instruction,\n reasoningSummary: row.reasoningSummary,\n accepted: row.accepted,\n metadata: row.metadata ?? {},\n createdAt: row.createdAt,\n }\n}\n\nfunction mapExport(row: SequenceExportRow): SequenceExportRecord {\n return {\n id: row.id,\n format: row.format,\n status: row.status,\n resultUrl: row.resultUrl,\n metadata: row.metadata ?? {},\n createdAt: row.createdAt,\n }\n}\n\nfunction assertFrame(value: number, label: string): void {\n if (!Number.isInteger(value) || value < 0) throw new Error(`${label} must be a non-negative integer`)\n}\n\nfunction assertClipDuration(durationFrames: number): void {\n if (!Number.isInteger(durationFrames) || durationFrames < MIN_SEQUENCE_CLIP_FRAMES) {\n throw new Error('durationFrames must be a positive integer')\n }\n}\n\nfunction assertListLimit(limit: number): void {\n if (!Number.isInteger(limit) || limit < 1) throw new Error('limit must be a positive integer')\n}\n"],"mappings":"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","names":["sql","sql"]}