@zodic/shared 0.0.297 → 0.0.299

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.
@@ -1,4 +1,4 @@
1
- import { eq } from 'drizzle-orm';
1
+ import { and, eq } from 'drizzle-orm';
2
2
  import { inject, injectable } from 'inversify';
3
3
  import { ChatMessages, schema } from '../..';
4
4
  import { KVArchetype, ZodiacSignSlug } from '../../types/scopes/legacy';
@@ -290,21 +290,21 @@ export class ArchetypeService {
290
290
  overrideExisting: boolean = false
291
291
  ) {
292
292
  const db = this.context.drizzle();
293
+ console.log(`🚀 [Single] Starting generation for combination: ${combination} | Override: ${overrideExisting}`);
294
+
293
295
  const [sun, ascendant, moon] = combination.split('-') as ZodiacSignSlug[];
294
-
295
296
  const prompt = generateArchetypePrompt([{ sun, ascendant, moon }]);
296
297
  const messages: ChatMessages = [{ role: 'user', content: prompt }];
297
298
  const response = await this.context.api().callTogether.single(messages, {});
298
-
299
+
299
300
  if (!response) {
300
- throw new Error(
301
- `No response when generating archetype names for ${combination}`
302
- );
301
+ console.error(`❌ [Single] No response for: ${combination}`);
302
+ return;
303
303
  }
304
-
304
+
305
305
  let blocks: string[] = [];
306
306
  let ptBlocks: string[] = [];
307
-
307
+
308
308
  try {
309
309
  blocks = response
310
310
  .split('-EN')[1]
@@ -312,14 +312,14 @@ export class ArchetypeService {
312
312
  .trim()
313
313
  .split(/\n\d\.\s*\n?/)
314
314
  .filter(Boolean);
315
-
315
+
316
316
  ptBlocks = response
317
317
  .split('-PT')[1]
318
318
  .trim()
319
319
  .split(/\n\d\.\s*\n?/)
320
320
  .filter(Boolean);
321
321
  } catch (err) {
322
- console.error(`Parsing failed for combination: ${combination}`, err);
322
+ console.error(`❌ [Single] Parsing failed for ${combination}`, err);
323
323
  await db.insert(schema.archetypeNameDumps).values({
324
324
  id: combination,
325
325
  combination,
@@ -329,24 +329,18 @@ export class ArchetypeService {
329
329
  });
330
330
  return;
331
331
  }
332
-
333
- const englishNames = blocks.map((block) => {
334
- const nameMatch = block.match(/• Name:\s*(.+)/);
335
- const essenceMatch = block.match(/• Essence:\s*(.+)/);
336
- return {
337
- name: nameMatch?.[1]?.trim() || '',
338
- essenceLine: essenceMatch?.[1]?.trim() || '',
339
- };
340
- });
341
-
342
- const portugueseVariants = ptBlocks.map((block) => {
343
- const masc = block.match(/• Masculino:\s*(.+)/)?.[1]?.trim() || '';
344
- const fem = block.match(/• Feminino:\s*(.+)/)?.[1]?.trim() || '';
345
- const essence = block.match(/• Essência:\s*(.+)/)?.[1]?.trim() || '';
346
- return { masc, fem, essenceLine: essence };
347
- });
348
-
349
- // Duplicate helper
332
+
333
+ const englishNames = blocks.map((block) => ({
334
+ name: block.match(/• Name:\s*(.+)/)?.[1]?.trim() || '',
335
+ essenceLine: block.match(/• Essence:\s*(.+)/)?.[1]?.trim() || '',
336
+ }));
337
+
338
+ const portugueseVariants = ptBlocks.map((block) => ({
339
+ masc: block.match(/• Masculino:\s*(.+)/)?.[1]?.trim() || '',
340
+ fem: block.match(/• Feminino:\s*(.+)/)?.[1]?.trim() || '',
341
+ essenceLine: block.match(/• Essência:\s*(.+)/)?.[1]?.trim() || '',
342
+ }));
343
+
350
344
  async function isEnglishNameDuplicate(name: string): Promise<boolean> {
351
345
  const result = await db
352
346
  .select({ name: schema.archetypesData.name })
@@ -359,117 +353,133 @@ export class ArchetypeService {
359
353
  )
360
354
  .limit(1)
361
355
  .execute();
362
-
356
+
363
357
  return result.length > 0;
364
358
  }
365
-
359
+
366
360
  await Promise.all(
367
361
  englishNames.map(async (entry, i) => {
368
362
  const index = (i + 1).toString();
369
363
  const ptVariant = portugueseVariants[i];
370
-
364
+
371
365
  if (await isEnglishNameDuplicate(entry.name)) {
372
- console.warn(`Duplicate name detected: "${entry.name}" — skipping.`);
366
+ console.warn(`⚠️ [Single] Duplicate name skipped: ${entry.name}`);
373
367
  return;
374
368
  }
375
-
369
+
376
370
  for (const gender of ['male', 'female']) {
377
371
  const enId = `${combination}:${gender}:${index}`;
378
372
  const ptId = `${combination}:${gender}:${index}:pt`;
379
373
  const ptName = gender === 'female' ? ptVariant.fem : ptVariant.masc;
380
-
381
- const existingEn = await db
382
- .select({ id: schema.archetypesData.id })
383
- .from(schema.archetypesData)
384
- .where(eq(schema.archetypesData.id, enId))
385
- .execute();
386
-
387
- if (overrideExisting || existingEn.length === 0) {
388
- await db
389
- .insert(schema.archetypesData)
390
- .values({
391
- id: enId,
392
- combination,
393
- gender,
394
- archetypeIndex: index,
395
- language: 'en-us',
396
- name: entry.name,
397
- essenceLine: entry.essenceLine,
398
- status: 'idle',
399
- })
400
- .onConflictDoUpdate({
401
- target: [schema.archetypesData.id],
402
- set: {
403
- name: entry.name,
404
- essenceLine: entry.essenceLine,
405
- updatedAt: new Date().getTime(),
406
- },
407
- });
408
- }
409
-
410
- const existingPt = await db
411
- .select({ id: schema.archetypesData.id })
412
- .from(schema.archetypesData)
413
- .where(eq(schema.archetypesData.id, ptId))
414
- .execute();
415
-
416
- if (overrideExisting || existingPt.length === 0) {
417
- await db
418
- .insert(schema.archetypesData)
419
- .values({
420
- id: ptId,
421
- combination,
422
- gender,
423
- archetypeIndex: index,
424
- language: 'pt-br',
425
- name: ptName,
426
- essenceLine: ptVariant.essenceLine,
427
- status: 'idle',
428
- })
429
- .onConflictDoUpdate({
430
- target: [schema.archetypesData.id],
431
- set: {
432
- name: ptName,
433
- essenceLine: ptVariant.essenceLine,
434
- updatedAt: new Date().getTime(),
435
- },
436
- });
437
- }
374
+
375
+ await db.insert(schema.archetypesData).values({
376
+ id: enId,
377
+ combination,
378
+ gender,
379
+ archetypeIndex: index,
380
+ language: 'en-us',
381
+ name: entry.name,
382
+ essenceLine: entry.essenceLine,
383
+ status: 'idle',
384
+ }).onConflictDoUpdate({
385
+ target: [schema.archetypesData.id],
386
+ set: {
387
+ name: entry.name,
388
+ essenceLine: entry.essenceLine,
389
+ updatedAt: new Date().getTime(),
390
+ },
391
+ });
392
+
393
+ await db.insert(schema.archetypesData).values({
394
+ id: ptId,
395
+ combination,
396
+ gender,
397
+ archetypeIndex: index,
398
+ language: 'pt-br',
399
+ name: ptName,
400
+ essenceLine: ptVariant.essenceLine,
401
+ status: 'idle',
402
+ }).onConflictDoUpdate({
403
+ target: [schema.archetypesData.id],
404
+ set: {
405
+ name: ptName,
406
+ essenceLine: ptVariant.essenceLine,
407
+ updatedAt: new Date().getTime(),
408
+ },
409
+ });
410
+
411
+ console.log(`✅ [Single] Saved archetype ${index} (${gender}) for ${combination}`);
438
412
  }
439
413
  })
440
414
  );
415
+
416
+ console.log(`🏁 [Single] Done generating names for ${combination}`);
441
417
  }
442
418
 
443
419
  async generateArchetypeNamesBatch(
444
420
  entries: Array<{ combination: string }>,
445
421
  overrideExisting: boolean = false
446
422
  ) {
423
+ const db = this.context.drizzle();
424
+ console.log(`🚀 [Batch] Starting generation for ${entries.length} combinations | Override: ${overrideExisting}`);
425
+
447
426
  const prompts = entries.map(({ combination }) => {
448
427
  const [sun, ascendant, moon] = combination.split('-') as ZodiacSignSlug[];
449
428
  return { sun, ascendant, moon };
450
429
  });
451
-
430
+
452
431
  const prompt = generateArchetypePrompt(prompts);
453
432
  const messages: ChatMessages = [{ role: 'user', content: prompt }];
454
433
  const response = await this.context.api().callTogether.single(messages, {});
455
-
434
+
456
435
  if (!response) {
457
- throw new Error('No response when generating batch archetype names');
436
+ console.error(`❌ [Batch] No response from model`);
437
+ return;
458
438
  }
459
-
460
- const db = this.context.drizzle();
461
-
439
+
462
440
  const blocks = response
463
441
  .split(/Composition \d+/)
464
442
  .slice(1)
465
443
  .map((b) => b.trim());
466
-
444
+
445
+ async function isEnglishNameDuplicate(name: string): Promise<boolean> {
446
+ const result = await db
447
+ .select({ name: schema.archetypesData.name })
448
+ .from(schema.archetypesData)
449
+ .where(
450
+ and(
451
+ eq(schema.archetypesData.language, 'en-us'),
452
+ eq(schema.archetypesData.name, name)
453
+ )
454
+ )
455
+ .limit(1)
456
+ .execute();
457
+
458
+ return result.length > 0;
459
+ }
460
+
467
461
  for (let i = 0; i < entries.length; i++) {
468
462
  const { combination } = entries[i];
469
463
  const block = blocks[i];
470
- const en = block.split('-EN')[1].split('-PT')[0].trim();
471
- const pt = block.split('-PT')[1].trim();
472
-
464
+ console.log(`📦 [Batch] Processing: ${combination}`);
465
+
466
+ let en = '';
467
+ let pt = '';
468
+ try {
469
+ en = block.split('-EN')[1].split('-PT')[0].trim();
470
+ pt = block.split('-PT')[1].trim();
471
+ } catch (err) {
472
+ console.error(`❌ [Batch] Parsing failed for: ${combination}`, err);
473
+ await db.insert(schema.archetypeNameDumps).values({
474
+ id: combination,
475
+ combination,
476
+ rawText: block,
477
+ parsedSuccessfully: 0,
478
+ createdAt: Date.now(),
479
+ });
480
+ continue;
481
+ }
482
+
473
483
  const english = en
474
484
  .split(/\n\d\.\s*\n?/)
475
485
  .filter(Boolean)
@@ -477,7 +487,7 @@ export class ArchetypeService {
477
487
  name: line.match(/• Name:\s*(.+)/)?.[1]?.trim() || '',
478
488
  essenceLine: line.match(/• Essence:\s*(.+)/)?.[1]?.trim() || '',
479
489
  }));
480
-
490
+
481
491
  const portuguese = pt
482
492
  .split(/\n\d\.\s*\n?/)
483
493
  .filter(Boolean)
@@ -486,76 +496,65 @@ export class ArchetypeService {
486
496
  fem: line.match(/• Feminino:\s*(.+)/)?.[1]?.trim() || '',
487
497
  essenceLine: line.match(/• Essência:\s*(.+)/)?.[1]?.trim() || '',
488
498
  }));
489
-
499
+
490
500
  for (let j = 0; j < 3; j++) {
491
501
  const index = (j + 1).toString();
492
502
  const englishEntry = english[j];
493
503
  const ptEntry = portuguese[j];
494
-
504
+
505
+ if (await isEnglishNameDuplicate(englishEntry.name)) {
506
+ console.warn(`⚠️ [Batch] Duplicate name skipped: ${englishEntry.name}`);
507
+ continue;
508
+ }
509
+
495
510
  for (const gender of ['male', 'female']) {
496
511
  const enId = `${combination}:${gender}:${index}`;
497
512
  const ptId = `${combination}:${gender}:${index}:pt`;
498
513
  const ptName = gender === 'female' ? ptEntry.fem : ptEntry.masc;
499
-
500
- const existingEn = await db
501
- .select({ id: schema.archetypesData.id })
502
- .from(schema.archetypesData)
503
- .where(eq(schema.archetypesData.id, enId))
504
- .execute();
505
-
506
- if (overrideExisting || existingEn.length === 0) {
507
- await db
508
- .insert(schema.archetypesData)
509
- .values({
510
- id: enId,
511
- combination,
512
- gender,
513
- archetypeIndex: index,
514
- language: 'en-us',
515
- name: englishEntry.name,
516
- essenceLine: englishEntry.essenceLine,
517
- status: 'idle',
518
- })
519
- .onConflictDoUpdate({
520
- target: [schema.archetypesData.id],
521
- set: {
522
- name: englishEntry.name,
523
- essenceLine: englishEntry.essenceLine,
524
- updatedAt: new Date().getTime(),
525
- },
526
- });
527
- }
528
-
529
- const existingPt = await db
530
- .select({ id: schema.archetypesData.id })
531
- .from(schema.archetypesData)
532
- .where(eq(schema.archetypesData.id, ptId))
533
- .execute();
534
-
535
- if (overrideExisting || existingPt.length === 0) {
536
- await db
537
- .insert(schema.archetypesData)
538
- .values({
539
- id: ptId,
540
- combination,
541
- gender,
542
- archetypeIndex: index,
543
- language: 'pt-br',
544
- name: ptName,
545
- essenceLine: ptEntry.essenceLine,
546
- status: 'idle',
547
- })
548
- .onConflictDoUpdate({
549
- target: [schema.archetypesData.id],
550
- set: {
551
- name: ptName,
552
- essenceLine: ptEntry.essenceLine,
553
- updatedAt: new Date().getTime(),
554
- },
555
- });
556
- }
514
+
515
+ await db.insert(schema.archetypesData).values({
516
+ id: enId,
517
+ combination,
518
+ gender,
519
+ archetypeIndex: index,
520
+ language: 'en-us',
521
+ name: englishEntry.name,
522
+ essenceLine: englishEntry.essenceLine,
523
+ status: 'idle',
524
+ }).onConflictDoUpdate({
525
+ target: [schema.archetypesData.id],
526
+ set: {
527
+ name: englishEntry.name,
528
+ essenceLine: englishEntry.essenceLine,
529
+ updatedAt: new Date().getTime(),
530
+ },
531
+ });
532
+
533
+ await db.insert(schema.archetypesData).values({
534
+ id: ptId,
535
+ combination,
536
+ gender,
537
+ archetypeIndex: index,
538
+ language: 'pt-br',
539
+ name: ptName,
540
+ essenceLine: ptEntry.essenceLine,
541
+ status: 'idle',
542
+ }).onConflictDoUpdate({
543
+ target: [schema.archetypesData.id],
544
+ set: {
545
+ name: ptName,
546
+ essenceLine: ptEntry.essenceLine,
547
+ updatedAt: new Date().getTime(),
548
+ },
549
+ });
550
+
551
+ console.log(`✅ [Batch] Saved archetype ${index} (${gender}) for ${combination}`);
557
552
  }
558
553
  }
554
+
555
+ console.log(`🏁 [Batch] Finished combination: ${combination}`);
559
556
  }
557
+
558
+ console.log(`🎉 [Batch] Completed processing for all ${entries.length} combinations`);
560
559
  }
561
560
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zodic/shared",
3
- "version": "0.0.297",
3
+ "version": "0.0.299",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -38,6 +38,7 @@ export type CentralBindings = {
38
38
  AMULET_QUEUE: Queue;
39
39
  LANTERN_QUEUE: Queue;
40
40
  ORB_QUEUE: Queue;
41
+ ARCHETYPE_POPULATION_QUEUE: Queue;
41
42
 
42
43
  PROMPT_IMAGE_DESCRIBER: string;
43
44
  PROMPT_GENERATE_ARCHETYPE_BASIC_INFO: string;
@@ -136,6 +137,7 @@ export type BackendBindings = Env &
136
137
  | 'RING_QUEUE'
137
138
  | 'LANTERN_QUEUE'
138
139
  | 'ORB_QUEUE'
140
+ | 'ARCHETYPE_POPULATION_QUEUE'
139
141
  | 'KV_API_USAGE'
140
142
  | 'KV_CONCEPT_CACHE'
141
143
  | 'ENV'