db4ai 0.3.0 → 0.3.1

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.
Files changed (89) hide show
  1. package/dist/chunk-3DWAMVV5.js +305 -0
  2. package/dist/chunk-3DWAMVV5.js.map +1 -0
  3. package/dist/chunk-COTPYBYM.js +618 -0
  4. package/dist/chunk-COTPYBYM.js.map +1 -0
  5. package/dist/chunk-EERD6CDF.js +735 -0
  6. package/dist/chunk-EERD6CDF.js.map +1 -0
  7. package/dist/chunk-FUF4HJTC.js +758 -0
  8. package/dist/chunk-FUF4HJTC.js.map +1 -0
  9. package/dist/chunk-JLL6FH5L.js +16 -0
  10. package/dist/chunk-JLL6FH5L.js.map +1 -0
  11. package/dist/chunk-JXFW6AIT.js +192 -0
  12. package/dist/chunk-JXFW6AIT.js.map +1 -0
  13. package/dist/chunk-XLSYCQPG.js +854 -0
  14. package/dist/chunk-XLSYCQPG.js.map +1 -0
  15. package/dist/chunk-Y5IXAS7F.js +569 -0
  16. package/dist/chunk-Y5IXAS7F.js.map +1 -0
  17. package/dist/cli/bin.d.ts +13 -12
  18. package/dist/cli/bin.js +277 -307
  19. package/dist/cli/bin.js.map +1 -1
  20. package/dist/cli/dashboard/index.d.ts +295 -14
  21. package/dist/cli/dashboard/index.js +60 -15
  22. package/dist/cli/dashboard/index.js.map +1 -1
  23. package/dist/cli/index.d.ts +10 -16
  24. package/dist/cli/index.js +94 -47
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/runtime/index.d.ts +52 -23
  27. package/dist/cli/runtime/index.js +10 -704
  28. package/dist/cli/runtime/index.js.map +1 -1
  29. package/dist/cli/scanner/index.d.ts +17 -15
  30. package/dist/cli/scanner/index.js +8 -639
  31. package/dist/cli/scanner/index.js.map +1 -1
  32. package/dist/cli/seed/index.d.ts +16 -12
  33. package/dist/cli/seed/index.js +12 -773
  34. package/dist/cli/seed/index.js.map +1 -1
  35. package/dist/cli/sync/index.d.ts +54 -53
  36. package/dist/cli/sync/index.js +23 -704
  37. package/dist/cli/sync/index.js.map +1 -1
  38. package/dist/cli/terminal.d.ts +9 -8
  39. package/dist/cli/terminal.js +6 -209
  40. package/dist/cli/terminal.js.map +1 -1
  41. package/dist/cli/workflow/index.d.ts +18 -10
  42. package/dist/cli/workflow/index.js +6 -307
  43. package/dist/cli/workflow/index.js.map +1 -1
  44. package/dist/handlers.d.ts +10 -9
  45. package/dist/handlers.js +6 -38
  46. package/dist/handlers.js.map +1 -1
  47. package/dist/index.d.ts +120 -118
  48. package/dist/index.js +1963 -3125
  49. package/dist/index.js.map +1 -1
  50. package/package.json +3 -4
  51. package/dist/cli/bin.d.ts.map +0 -1
  52. package/dist/cli/dashboard/App.d.ts +0 -16
  53. package/dist/cli/dashboard/App.d.ts.map +0 -1
  54. package/dist/cli/dashboard/App.js +0 -116
  55. package/dist/cli/dashboard/App.js.map +0 -1
  56. package/dist/cli/dashboard/components/index.d.ts +0 -70
  57. package/dist/cli/dashboard/components/index.d.ts.map +0 -1
  58. package/dist/cli/dashboard/components/index.js +0 -192
  59. package/dist/cli/dashboard/components/index.js.map +0 -1
  60. package/dist/cli/dashboard/hooks/index.d.ts +0 -76
  61. package/dist/cli/dashboard/hooks/index.d.ts.map +0 -1
  62. package/dist/cli/dashboard/hooks/index.js +0 -201
  63. package/dist/cli/dashboard/hooks/index.js.map +0 -1
  64. package/dist/cli/dashboard/index.d.ts.map +0 -1
  65. package/dist/cli/dashboard/types.d.ts +0 -84
  66. package/dist/cli/dashboard/types.d.ts.map +0 -1
  67. package/dist/cli/dashboard/types.js +0 -5
  68. package/dist/cli/dashboard/types.js.map +0 -1
  69. package/dist/cli/dashboard/views/index.d.ts +0 -51
  70. package/dist/cli/dashboard/views/index.d.ts.map +0 -1
  71. package/dist/cli/dashboard/views/index.js +0 -72
  72. package/dist/cli/dashboard/views/index.js.map +0 -1
  73. package/dist/cli/index.d.ts.map +0 -1
  74. package/dist/cli/runtime/index.d.ts.map +0 -1
  75. package/dist/cli/scanner/index.d.ts.map +0 -1
  76. package/dist/cli/seed/index.d.ts.map +0 -1
  77. package/dist/cli/sync/index.d.ts.map +0 -1
  78. package/dist/cli/terminal.d.ts.map +0 -1
  79. package/dist/cli/workflow/index.d.ts.map +0 -1
  80. package/dist/errors.d.ts +0 -43
  81. package/dist/errors.d.ts.map +0 -1
  82. package/dist/errors.js +0 -47
  83. package/dist/errors.js.map +0 -1
  84. package/dist/handlers.d.ts.map +0 -1
  85. package/dist/index.d.ts.map +0 -1
  86. package/dist/types.d.ts +0 -276
  87. package/dist/types.d.ts.map +0 -1
  88. package/dist/types.js +0 -12
  89. package/dist/types.js.map +0 -1
@@ -0,0 +1,735 @@
1
+ // cli/seed/index.ts
2
+ var SeedError = class extends Error {
3
+ seedName;
4
+ type;
5
+ position;
6
+ constructor(message, context) {
7
+ super(message);
8
+ this.name = "SeedError";
9
+ if (context) {
10
+ this.seedName = context.seedName;
11
+ this.type = context.type;
12
+ this.position = context.position;
13
+ }
14
+ }
15
+ };
16
+ function Seed(input) {
17
+ if (!input.data && !input.source) {
18
+ throw new SeedError("Static seed must have data or source");
19
+ }
20
+ return {
21
+ kind: "static",
22
+ type: input.type,
23
+ data: input.data,
24
+ source: input.source,
25
+ headers: input.headers,
26
+ dataPath: input.dataPath,
27
+ nextPath: input.nextPath,
28
+ retries: input.retries,
29
+ transform: input.transform,
30
+ fieldMapping: input.fieldMapping,
31
+ readOnly: input.readOnly,
32
+ concurrency: input.concurrency
33
+ };
34
+ }
35
+ function Generate(input) {
36
+ const count = input.count ?? (input.ids ? void 0 : 1);
37
+ if (count === void 0 && !input.ids) {
38
+ throw new SeedError("Generated seed must have count or ids");
39
+ }
40
+ return {
41
+ kind: "generated",
42
+ type: input.type,
43
+ count,
44
+ ids: input.ids,
45
+ prompt: input.prompt,
46
+ constraints: input.constraints,
47
+ variations: input.variations,
48
+ cascade: input.cascade,
49
+ cascadeDepth: input.cascadeDepth,
50
+ cascadeReuse: input.cascadeReuse,
51
+ readOnly: input.readOnly,
52
+ concurrency: input.concurrency
53
+ };
54
+ }
55
+ function createSeedRunner(db, options) {
56
+ const {
57
+ seeds,
58
+ onProgress,
59
+ onCheckpoint,
60
+ onWarning,
61
+ onEntity,
62
+ beforeSeed,
63
+ afterSeed,
64
+ continueOnError = false,
65
+ timeout,
66
+ order,
67
+ validateSchema = false,
68
+ concurrency: globalConcurrency = 1,
69
+ dryRun = false,
70
+ skipExisting = false,
71
+ storage,
72
+ persist = false,
73
+ enableCache = false,
74
+ batchSize = 1
75
+ } = options;
76
+ const seedResultCache = /* @__PURE__ */ new Map();
77
+ const entityExistsCache = /* @__PURE__ */ new Map();
78
+ function getEntityCacheKey(type, id) {
79
+ return `${type}:${id}`;
80
+ }
81
+ async function checkEntityExists(type, id) {
82
+ const cacheKey = getEntityCacheKey(type, id);
83
+ if (enableCache && entityExistsCache.has(cacheKey)) {
84
+ return entityExistsCache.get(cacheKey);
85
+ }
86
+ const existing = await db.get(type, id);
87
+ const exists = existing !== null && existing !== void 0;
88
+ if (enableCache) {
89
+ entityExistsCache.set(cacheKey, exists);
90
+ }
91
+ return exists;
92
+ }
93
+ function markEntityCreated(type, id) {
94
+ if (enableCache) {
95
+ entityExistsCache.set(getEntityCacheKey(type, id), true);
96
+ }
97
+ }
98
+ function clearCaches() {
99
+ seedResultCache.clear();
100
+ entityExistsCache.clear();
101
+ }
102
+ async function processBatch(batch, seedName, total, phase, startTime) {
103
+ if (batch.length === 0) return 0;
104
+ let createdCount = 0;
105
+ await Promise.all(
106
+ batch.map(async (item) => {
107
+ await db.create(item.type, item.data);
108
+ markEntityCreated(item.type, item.data.id);
109
+ createdCount++;
110
+ if (onEntity) {
111
+ onEntity(item.type, item.data);
112
+ }
113
+ reportProgress(seedName, item.type, phase, item.position, total, startTime);
114
+ })
115
+ );
116
+ return createdCount;
117
+ }
118
+ function reportProgress(seedName, type, phase, position, total, startTime) {
119
+ if (onCheckpoint) {
120
+ onCheckpoint(position);
121
+ }
122
+ if (onProgress) {
123
+ const elapsedMs = Date.now() - startTime;
124
+ const rate = position / (elapsedMs / 1e3);
125
+ const eta = total > position ? Math.round(elapsedMs / position * (total - position)) : 0;
126
+ onProgress({
127
+ seedName,
128
+ type,
129
+ phase,
130
+ current: position,
131
+ total,
132
+ percentage: Math.round(position / total * 100),
133
+ rate,
134
+ eta
135
+ });
136
+ }
137
+ }
138
+ async function persistCheckpoint(seedName, position, total) {
139
+ if (persist && storage) {
140
+ await storage.set(
141
+ `seed:${seedName}:state`,
142
+ JSON.stringify({ position, total })
143
+ );
144
+ }
145
+ }
146
+ function extractReferences(typeDef) {
147
+ const refs = [];
148
+ if (!typeDef || typeof typeDef !== "object") return refs;
149
+ for (const [field, value] of Object.entries(typeDef)) {
150
+ if (typeof value === "string") {
151
+ const hardMatch = value.match(/^->([A-Z][a-zA-Z0-9]*)/);
152
+ if (hardMatch) {
153
+ refs.push({ type: hardMatch[1], fuzzy: false, field });
154
+ }
155
+ const fuzzyMatch = value.match(/^~>([A-Z][a-zA-Z0-9]*)/);
156
+ if (fuzzyMatch) {
157
+ refs.push({ type: fuzzyMatch[1], fuzzy: true, field });
158
+ }
159
+ }
160
+ }
161
+ return refs;
162
+ }
163
+ function extractReferenceTypes(typeDef) {
164
+ return extractReferences(typeDef).map((r) => r.type);
165
+ }
166
+ function isReadOnlyType(typeName) {
167
+ const typeDef = db.schema[typeName];
168
+ if (typeDef && typeof typeDef === "object" && "_readOnly" in typeDef) {
169
+ return !!typeDef._readOnly;
170
+ }
171
+ return false;
172
+ }
173
+ function getSeedType(config) {
174
+ return config.type;
175
+ }
176
+ function computeExecutionOrder() {
177
+ const seedNames = Object.keys(seeds);
178
+ const deps = /* @__PURE__ */ new Map();
179
+ const typeToSeed = /* @__PURE__ */ new Map();
180
+ for (const name of seedNames) {
181
+ deps.set(name, /* @__PURE__ */ new Set());
182
+ typeToSeed.set(getSeedType(seeds[name]), name);
183
+ }
184
+ for (const name of seedNames) {
185
+ const config = seeds[name];
186
+ const typeDef = db.schema[config.type];
187
+ const refs = extractReferenceTypes(typeDef);
188
+ for (const ref of refs) {
189
+ const depSeed = typeToSeed.get(ref);
190
+ if (depSeed && depSeed !== name) {
191
+ deps.get(name).add(depSeed);
192
+ }
193
+ }
194
+ }
195
+ const staticSeeds = seedNames.filter((n) => seeds[n].kind === "static");
196
+ const generatedSeeds = seedNames.filter((n) => seeds[n].kind === "generated");
197
+ for (const gen of generatedSeeds) {
198
+ for (const stat of staticSeeds) {
199
+ if (!deps.get(gen).has(stat)) {
200
+ deps.get(gen).add(stat);
201
+ }
202
+ }
203
+ }
204
+ const result = [];
205
+ const visited = /* @__PURE__ */ new Set();
206
+ const visiting = /* @__PURE__ */ new Set();
207
+ function visit(name) {
208
+ if (visited.has(name)) return;
209
+ if (visiting.has(name)) {
210
+ throw new SeedError(`Circular dependency detected involving seed "${name}"`);
211
+ }
212
+ visiting.add(name);
213
+ for (const dep of deps.get(name) || []) {
214
+ visit(dep);
215
+ }
216
+ visiting.delete(name);
217
+ visited.add(name);
218
+ result.push(name);
219
+ }
220
+ for (const name of seedNames) {
221
+ visit(name);
222
+ }
223
+ return result;
224
+ }
225
+ function applyFieldMapping(data, mapping) {
226
+ const result = {};
227
+ for (const [from, to] of Object.entries(mapping)) {
228
+ if (from in data) {
229
+ result[to] = data[from];
230
+ }
231
+ }
232
+ for (const [key, value] of Object.entries(data)) {
233
+ if (!(key in mapping)) {
234
+ result[key] = value;
235
+ }
236
+ }
237
+ return result;
238
+ }
239
+ function extractDataPath(data, path) {
240
+ if (!path.startsWith("$.")) return Array.isArray(data) ? data : [];
241
+ const key = path.slice(2);
242
+ if (data && typeof data === "object" && key in data) {
243
+ const result = data[key];
244
+ return Array.isArray(result) ? result : [];
245
+ }
246
+ return [];
247
+ }
248
+ function extractNextPath(data, path) {
249
+ if (!path.startsWith("$.")) return null;
250
+ const key = path.slice(2);
251
+ if (data && typeof data === "object" && key in data) {
252
+ const result = data[key];
253
+ return typeof result === "string" ? result : null;
254
+ }
255
+ return null;
256
+ }
257
+ async function fetchWithRetry(url, headers, retries = 1) {
258
+ let lastError;
259
+ for (let i = 0; i < retries; i++) {
260
+ try {
261
+ const response = headers ? await fetch(url, { headers }) : await fetch(url);
262
+ if (response.ok) return response;
263
+ if (i === retries - 1) {
264
+ throw new SeedError(
265
+ `API request failed: ${response.status} ${response.statusText}`
266
+ );
267
+ }
268
+ } catch (error) {
269
+ lastError = error;
270
+ if (i === retries - 1) {
271
+ throw lastError;
272
+ }
273
+ }
274
+ }
275
+ throw lastError || new SeedError("Fetch failed");
276
+ }
277
+ function withTimeout(promise, ms) {
278
+ if (!ms) return promise;
279
+ return new Promise((resolve, reject) => {
280
+ const timer = setTimeout(() => {
281
+ reject(new SeedError("Operation timeout exceeded"));
282
+ }, ms);
283
+ promise.then((result) => {
284
+ clearTimeout(timer);
285
+ resolve(result);
286
+ }).catch((error) => {
287
+ clearTimeout(timer);
288
+ reject(error);
289
+ });
290
+ });
291
+ }
292
+ async function runWithConcurrency(items, fn, limit) {
293
+ const results = new Array(items.length);
294
+ let currentIndex = 0;
295
+ async function runNext() {
296
+ while (currentIndex < items.length) {
297
+ const index = currentIndex++;
298
+ results[index] = await fn(items[index], index);
299
+ }
300
+ }
301
+ const workers = Array.from(
302
+ { length: Math.min(limit, items.length) },
303
+ () => runNext()
304
+ );
305
+ await Promise.all(workers);
306
+ return results;
307
+ }
308
+ function selectVariation(variations, index, total) {
309
+ if (variations.length === 0) return {};
310
+ const totalWeight = variations.reduce((sum, v) => sum + (v.weight ?? 1), 0);
311
+ const normalizedWeights = variations.map((v) => (v.weight ?? 1) / totalWeight);
312
+ let cumulative = 0;
313
+ const position = index / total;
314
+ for (let i = 0; i < variations.length; i++) {
315
+ cumulative += normalizedWeights[i];
316
+ if (position < cumulative || i === variations.length - 1) {
317
+ const { weight: _2, ...rest2 } = variations[i];
318
+ return rest2;
319
+ }
320
+ }
321
+ const { weight: _, ...rest } = variations[0];
322
+ return rest;
323
+ }
324
+ async function cascadeGenerate(typeName, result, remainingDepth, reuse, visited) {
325
+ if (remainingDepth <= 0) return;
326
+ const typeDef = db.schema[typeName];
327
+ const refs = extractReferences(typeDef);
328
+ for (const ref of refs) {
329
+ const visitKey = `${typeName}:${ref.field}:${ref.type}`;
330
+ if (visited.has(visitKey)) continue;
331
+ visited.add(visitKey);
332
+ if (ref.fuzzy) {
333
+ await db.list(ref.type);
334
+ continue;
335
+ }
336
+ if (isReadOnlyType(ref.type)) continue;
337
+ const refId = result && typeof result === "object" ? result[ref.field] : void 0;
338
+ if (reuse && refId) {
339
+ const existing = await db.get(ref.type, refId);
340
+ if (existing) continue;
341
+ }
342
+ const generatedRef = await db.generate({
343
+ type: ref.type,
344
+ prompt: `${ref.type} for ${typeName}`
345
+ });
346
+ if (remainingDepth > 1) {
347
+ await cascadeGenerate(
348
+ ref.type,
349
+ generatedRef,
350
+ remainingDepth - 1,
351
+ reuse,
352
+ visited
353
+ );
354
+ }
355
+ }
356
+ }
357
+ function validateSchemaField(typeName, fieldName, strict) {
358
+ const typeDef = db.schema[typeName];
359
+ if (!typeDef || typeof typeDef !== "object") {
360
+ if (strict) {
361
+ throw new SeedError(`Type "${typeName}" not found in schema`);
362
+ }
363
+ return false;
364
+ }
365
+ if (fieldName === "weight") return true;
366
+ if (!(fieldName in typeDef)) {
367
+ if (strict) {
368
+ throw new SeedError(`Field "${fieldName}" not found in ${typeName}`);
369
+ }
370
+ if (onWarning) {
371
+ onWarning(`Field "${fieldName}" not found in ${typeName}`);
372
+ }
373
+ return false;
374
+ }
375
+ return true;
376
+ }
377
+ async function runSeed(seedName, config, runOpts) {
378
+ const startTime = Date.now();
379
+ const errors = [];
380
+ let created = 0;
381
+ let skipped = 0;
382
+ let partial = false;
383
+ let resumeToken;
384
+ let startPosition = 0;
385
+ if (runOpts?.resume) {
386
+ try {
387
+ const resumeData = JSON.parse(
388
+ Buffer.from(runOpts.resume, "base64").toString()
389
+ );
390
+ if (resumeData[seedName]?.position) {
391
+ startPosition = resumeData[seedName].position;
392
+ }
393
+ } catch {
394
+ }
395
+ }
396
+ if (validateSchema === true) {
397
+ if (!db.schema[config.type]) {
398
+ throw new SeedError(`Type "${config.type}" not found in schema`, {
399
+ seedName,
400
+ type: config.type
401
+ });
402
+ }
403
+ }
404
+ const phase = config.kind === "static" ? "static" : "generated";
405
+ if (config.kind === "static") {
406
+ let data;
407
+ if (config.data) {
408
+ data = [...config.data];
409
+ if (config.transform) {
410
+ data = await config.transform(data);
411
+ }
412
+ } else if (config.source) {
413
+ let allData = [];
414
+ let url = config.source;
415
+ while (url) {
416
+ const response = await fetchWithRetry(url, config.headers, config.retries || 1);
417
+ const json = await response.json();
418
+ if (config.transform) {
419
+ const transformed = await config.transform(json);
420
+ allData = allData.concat(transformed);
421
+ if (config.nextPath) {
422
+ url = extractNextPath(json, config.nextPath);
423
+ } else {
424
+ url = null;
425
+ }
426
+ } else if (config.dataPath) {
427
+ const pageData = extractDataPath(json, config.dataPath);
428
+ allData = allData.concat(pageData);
429
+ if (config.nextPath) {
430
+ url = extractNextPath(json, config.nextPath);
431
+ } else {
432
+ url = null;
433
+ }
434
+ } else if (Array.isArray(json)) {
435
+ allData = allData.concat(json);
436
+ url = null;
437
+ } else if (json.data && Array.isArray(json.data)) {
438
+ allData = allData.concat(json.data);
439
+ url = null;
440
+ } else {
441
+ allData.push(json);
442
+ url = null;
443
+ }
444
+ }
445
+ data = allData;
446
+ } else {
447
+ data = [];
448
+ }
449
+ if (config.fieldMapping) {
450
+ data = data.map(
451
+ (item) => applyFieldMapping(item, config.fieldMapping)
452
+ );
453
+ }
454
+ const total = data.length;
455
+ const concurrency = config.concurrency ?? globalConcurrency;
456
+ const processItem = async (item, index) => {
457
+ const position = index + 1;
458
+ const id = item.id;
459
+ if (id) {
460
+ const exists = await checkEntityExists(config.type, id);
461
+ if (exists) {
462
+ skipped++;
463
+ return;
464
+ }
465
+ }
466
+ const entityData = config.readOnly ? { ...item, _readOnly: true } : { ...item };
467
+ if (!entityData.id) {
468
+ const name = entityData.name;
469
+ entityData.id = name ? name.toLowerCase().replace(/\s+/g, "-") : `${config.type.toLowerCase()}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
470
+ }
471
+ if (!dryRun) {
472
+ await db.create(config.type, entityData);
473
+ markEntityCreated(config.type, entityData.id);
474
+ if (onEntity) {
475
+ onEntity(config.type, entityData);
476
+ }
477
+ }
478
+ created++;
479
+ reportProgress(seedName, config.type, phase, position, total, startTime);
480
+ await persistCheckpoint(seedName, position, total);
481
+ };
482
+ if (concurrency > 1) {
483
+ await runWithConcurrency(
484
+ data,
485
+ processItem,
486
+ concurrency
487
+ );
488
+ } else {
489
+ for (let i = 0; i < data.length; i++) {
490
+ await processItem(data[i], i);
491
+ }
492
+ }
493
+ } else {
494
+ const count = config.ids?.length ?? config.count ?? 1;
495
+ const total = count - startPosition;
496
+ const concurrency = config.concurrency ?? globalConcurrency;
497
+ if (validateSchema && config.constraints) {
498
+ const strict = validateSchema === true;
499
+ for (const field of Object.keys(config.constraints)) {
500
+ validateSchemaField(config.type, field, strict);
501
+ }
502
+ }
503
+ if (validateSchema && config.variations) {
504
+ const strict = validateSchema === true;
505
+ for (const variation of config.variations) {
506
+ for (const field of Object.keys(variation)) {
507
+ if (field !== "weight") {
508
+ validateSchemaField(config.type, field, strict);
509
+ }
510
+ }
511
+ }
512
+ }
513
+ let resolvedConstraints = config.constraints ? { ...config.constraints } : void 0;
514
+ if (resolvedConstraints) {
515
+ for (const [key, value] of Object.entries(resolvedConstraints)) {
516
+ if (value && typeof value === "object" && "ref" in value) {
517
+ const refType = value.ref;
518
+ await db.list(refType);
519
+ }
520
+ }
521
+ }
522
+ const generateEntity = async (index) => {
523
+ const actualIndex = startPosition + index;
524
+ const position = actualIndex + 1;
525
+ const id = config.ids?.[actualIndex];
526
+ if (skipExisting && id) {
527
+ const exists = await checkEntityExists(config.type, id);
528
+ if (exists) {
529
+ skipped++;
530
+ return;
531
+ }
532
+ }
533
+ let variationProps = {};
534
+ if (config.variations && config.variations.length > 0) {
535
+ variationProps = selectVariation(config.variations, actualIndex, count);
536
+ }
537
+ try {
538
+ const generateConfig = {
539
+ type: config.type,
540
+ prompt: config.prompt,
541
+ constraints: resolvedConstraints,
542
+ ...variationProps
543
+ };
544
+ if (id) {
545
+ generateConfig.id = id;
546
+ }
547
+ if (!dryRun) {
548
+ const result = await withTimeout(
549
+ db.generate(generateConfig),
550
+ timeout
551
+ );
552
+ if (config.cascade) {
553
+ await cascadeGenerate(
554
+ config.type,
555
+ result,
556
+ config.cascadeDepth ?? Infinity,
557
+ config.cascadeReuse ?? false,
558
+ /* @__PURE__ */ new Set()
559
+ );
560
+ }
561
+ if (onEntity) {
562
+ onEntity(config.type, result);
563
+ }
564
+ }
565
+ created++;
566
+ reportProgress(seedName, config.type, phase, position, count, startTime);
567
+ await persistCheckpoint(seedName, position, count);
568
+ } catch (error) {
569
+ const errorMessage = error instanceof Error ? error.message : String(error);
570
+ const errorInfo = {
571
+ message: errorMessage,
572
+ position
573
+ };
574
+ if (error && typeof error === "object" && "code" in error && error.code === "INTERRUPTED") {
575
+ partial = true;
576
+ resumeToken = Buffer.from(
577
+ JSON.stringify({ [seedName]: { position } })
578
+ ).toString("base64");
579
+ errors.push(errorInfo);
580
+ return;
581
+ }
582
+ if (continueOnError) {
583
+ errors.push(errorInfo);
584
+ } else {
585
+ throw new SeedError(errorMessage, {
586
+ seedName,
587
+ type: config.type,
588
+ position
589
+ });
590
+ }
591
+ }
592
+ };
593
+ if (concurrency > 1) {
594
+ const indices = Array.from({ length: total }, (_, i) => i);
595
+ await runWithConcurrency(indices, generateEntity, concurrency);
596
+ } else {
597
+ for (let i = 0; i < total; i++) {
598
+ await generateEntity(i);
599
+ }
600
+ }
601
+ }
602
+ return {
603
+ success: errors.length === 0,
604
+ created,
605
+ skipped,
606
+ errors,
607
+ partial,
608
+ duration: Date.now() - startTime,
609
+ resumeToken
610
+ };
611
+ }
612
+ async function run(seedName, runOpts) {
613
+ const config = seeds[seedName];
614
+ if (!config) {
615
+ throw new SeedError(`Seed "${seedName}" not found`, { seedName });
616
+ }
617
+ if (!config.kind) {
618
+ throw new SeedError(`Invalid seed configuration for "${seedName}"`, { seedName });
619
+ }
620
+ let effectiveConfig = config;
621
+ if (beforeSeed) {
622
+ const hookResult = beforeSeed(seedName, config);
623
+ if (hookResult === null) {
624
+ return {
625
+ success: true,
626
+ created: 0,
627
+ skipped: 0,
628
+ errors: [],
629
+ partial: false,
630
+ duration: 0
631
+ };
632
+ }
633
+ if (hookResult) {
634
+ effectiveConfig = hookResult;
635
+ }
636
+ }
637
+ const result = await runSeed(seedName, effectiveConfig, runOpts);
638
+ if (afterSeed) {
639
+ afterSeed(seedName, result);
640
+ }
641
+ return result;
642
+ }
643
+ async function runAll() {
644
+ const startTime = Date.now();
645
+ const executionOrder = order ?? computeExecutionOrder();
646
+ if (dryRun) {
647
+ const wouldCreate = {};
648
+ for (const seedName of executionOrder) {
649
+ const config = seeds[seedName];
650
+ if (validateSchema === true) {
651
+ if (!db.schema[config.type]) {
652
+ throw new SeedError(`Type "${config.type}" not found in schema`, {
653
+ seedName,
654
+ type: config.type
655
+ });
656
+ }
657
+ }
658
+ if (config.kind === "static") {
659
+ wouldCreate[config.type] = config.data?.length ?? 0;
660
+ } else {
661
+ wouldCreate[config.type] = config.ids?.length ?? config.count ?? 1;
662
+ }
663
+ }
664
+ return {
665
+ success: true,
666
+ created: 0,
667
+ skipped: 0,
668
+ errors: [],
669
+ partial: false,
670
+ duration: Date.now() - startTime,
671
+ dryRun: true,
672
+ wouldCreate,
673
+ executionOrder
674
+ };
675
+ }
676
+ let totalCreated = 0;
677
+ let totalSkipped = 0;
678
+ const allErrors = [];
679
+ for (const seedName of executionOrder) {
680
+ const result = await run(seedName);
681
+ totalCreated += result.created;
682
+ totalSkipped += result.skipped;
683
+ allErrors.push(...result.errors);
684
+ }
685
+ return {
686
+ success: allErrors.length === 0,
687
+ created: totalCreated,
688
+ skipped: totalSkipped,
689
+ errors: allErrors,
690
+ partial: false,
691
+ duration: Date.now() - startTime
692
+ };
693
+ }
694
+ async function reset(seedName, resetOpts) {
695
+ const config = seeds[seedName];
696
+ if (!config) {
697
+ throw new SeedError(`Seed "${seedName}" not found`, { seedName });
698
+ }
699
+ await db.clear(config.type);
700
+ if (resetOpts?.cascade) {
701
+ const typeDef = db.schema[config.type];
702
+ const refs = extractReferenceTypes(typeDef);
703
+ for (const refType of refs) {
704
+ if (!isReadOnlyType(refType)) {
705
+ await db.clear(refType);
706
+ }
707
+ }
708
+ }
709
+ return run(seedName);
710
+ }
711
+ async function resetAll(resetOpts) {
712
+ for (const seedName of Object.keys(seeds)) {
713
+ const config = seeds[seedName];
714
+ if (resetOpts?.preserveReadOnly && config.readOnly) {
715
+ continue;
716
+ }
717
+ await db.clear(config.type);
718
+ }
719
+ return runAll();
720
+ }
721
+ return {
722
+ run,
723
+ runAll,
724
+ reset,
725
+ resetAll
726
+ };
727
+ }
728
+
729
+ export {
730
+ SeedError,
731
+ Seed,
732
+ Generate,
733
+ createSeedRunner
734
+ };
735
+ //# sourceMappingURL=chunk-EERD6CDF.js.map