@cadenza.io/service 2.0.0 → 2.0.2

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.
package/dist/index.mjs CHANGED
@@ -68,7 +68,7 @@ var DeputyTask = class extends Task {
68
68
  (responseCtx) => {
69
69
  console.log(
70
70
  "Resolving deputy",
71
- remoteRoutineName,
71
+ context.__localTaskName,
72
72
  responseCtx.errored ? responseCtx.__error : ""
73
73
  );
74
74
  if (responseCtx?.errored) {
@@ -334,35 +334,38 @@ var ServiceRegistry = class _ServiceRegistry {
334
334
  this.handleGlobalSignalRegistrationTask = CadenzaService.createMetaTask(
335
335
  "Handle global Signal Registration",
336
336
  (ctx) => {
337
- const { signalToTaskMap } = ctx;
338
- const sortedSignalToTaskMap = signalToTaskMap.sort((a, b) => {
339
- if (a.deleted && !b.deleted) return -1;
340
- if (!a.deleted && b.deleted) return 1;
341
- return 0;
342
- });
337
+ const { signalToTaskMaps } = ctx;
338
+ const sortedSignalToTaskMap = signalToTaskMaps.sort(
339
+ (a, b) => {
340
+ if (a.deleted && !b.deleted) return -1;
341
+ if (!a.deleted && b.deleted) return 1;
342
+ return 0;
343
+ }
344
+ );
345
+ console.log("signalToTaskMap", sortedSignalToTaskMap);
343
346
  const locallyEmittedSignals = CadenzaService.broker.listEmittedSignals().filter((s) => s.startsWith("global."));
344
347
  for (const map of sortedSignalToTaskMap) {
345
348
  if (map.deleted) {
346
- this.remoteSignals.get(map.taskServiceName)?.delete(map.signal);
347
- if (!this.remoteSignals.get(map.taskServiceName)?.size) {
348
- this.remoteSignals.delete(map.taskServiceName);
349
+ this.remoteSignals.get(map.serviceName)?.delete(map.signalName);
350
+ if (!this.remoteSignals.get(map.serviceName)?.size) {
351
+ this.remoteSignals.delete(map.serviceName);
349
352
  }
350
353
  CadenzaService.get(
351
- `Transmit signal: ${map.signal} to ${map.taskServiceName}`
354
+ `Transmit signal: ${map.signalName} to ${map.serviceName}`
352
355
  )?.destroy();
353
356
  continue;
354
357
  }
355
- if (locallyEmittedSignals.includes(map.signal)) {
356
- if (!this.remoteSignals.get(map.taskServiceName)) {
357
- this.remoteSignals.set(map.taskServiceName, /* @__PURE__ */ new Set());
358
+ if (locallyEmittedSignals.includes(map.signalName)) {
359
+ if (!this.remoteSignals.get(map.serviceName)) {
360
+ this.remoteSignals.set(map.serviceName, /* @__PURE__ */ new Set());
358
361
  }
359
- if (!this.remoteSignals.get(map.taskServiceName)?.has(map.signal)) {
362
+ if (!this.remoteSignals.get(map.serviceName)?.has(map.signalName)) {
360
363
  CadenzaService.createSignalTransmissionTask(
361
- map.signal,
362
- map.taskServiceName
364
+ map.signalName,
365
+ map.serviceName
363
366
  );
364
367
  }
365
- this.remoteSignals.get(map.taskServiceName)?.add(map.signal);
368
+ this.remoteSignals.get(map.serviceName)?.add(map.signalName);
366
369
  }
367
370
  }
368
371
  return true;
@@ -459,45 +462,43 @@ var ServiceRegistry = class _ServiceRegistry {
459
462
  },
460
463
  "Handles status update from socket broadcast"
461
464
  ).doOn("meta.socket_client.status_received");
462
- this.fullSyncTask = CadenzaService.createCadenzaDBQueryTask("service_instance", {
463
- filter: {
464
- deleted: false,
465
- is_active: true,
466
- is_non_responsive: false,
467
- is_blocked: false
468
- },
469
- fields: [
470
- "uuid",
471
- "address",
472
- "port",
473
- "service_name",
474
- "is_active",
475
- "is_non_responsive",
476
- "is_blocked",
477
- "health",
478
- "exposed",
479
- "created",
480
- "is_frontend"
481
- ]
482
- }).doOn("meta.sync_requested").emits("meta.service_registry.synced_instances").then(
483
- CadenzaService.createMetaTask(
484
- "Split service instances",
485
- function* (ctx) {
486
- const { serviceInstances } = ctx;
487
- if (!serviceInstances) {
488
- CadenzaService.log(
489
- "SyncFailed: No service instances found",
490
- ctx,
491
- "error"
492
- );
493
- return;
494
- }
495
- for (const serviceInstance of serviceInstances) {
496
- yield { serviceInstance };
497
- }
498
- }
499
- ).then(this.handleInstanceUpdateTask).doOn("meta.signal_controller.signal_map_added")
500
- );
465
+ const mergeSyncDataTask = CadenzaService.createUniqueMetaTask(
466
+ "Merge sync data",
467
+ (ctx) => {
468
+ let joinedContext = {};
469
+ ctx.joinedContexts.forEach((ctx2) => {
470
+ joinedContext = { ...joinedContext, ...ctx2 };
471
+ });
472
+ console.log("Full sync joinedContext", joinedContext);
473
+ return joinedContext;
474
+ }
475
+ ).then(this.handleGlobalSignalRegistrationTask);
476
+ this.fullSyncTask = CadenzaService.createMetaRoutine("Full sync", [
477
+ CadenzaService.createCadenzaDBQueryTask("signal_to_task_map", {
478
+ fields: ["signal_name", "service_name", "deleted"]
479
+ }).then(mergeSyncDataTask),
480
+ CadenzaService.createCadenzaDBQueryTask("service_instance", {
481
+ filter: {
482
+ deleted: false,
483
+ is_active: true,
484
+ is_non_responsive: false,
485
+ is_blocked: false
486
+ },
487
+ fields: [
488
+ "uuid",
489
+ "address",
490
+ "port",
491
+ "service_name",
492
+ "is_active",
493
+ "is_non_responsive",
494
+ "is_blocked",
495
+ "health",
496
+ "exposed",
497
+ "created",
498
+ "is_frontend"
499
+ ]
500
+ }).then(mergeSyncDataTask)
501
+ ]).doOn("meta.sync_requested");
501
502
  this.getInstanceById = CadenzaService.createMetaTask(
502
503
  "Get instance by id",
503
504
  (context) => {
@@ -713,15 +714,6 @@ var ServiceRegistry = class _ServiceRegistry {
713
714
  retryDelayMax: 6e4,
714
715
  retryDelayFactor: 1.3
715
716
  }
716
- ).then(
717
- CadenzaService.createMetaTask(
718
- "Set service name",
719
- ({ __serviceName }) => {
720
- this.serviceName = __serviceName;
721
- return true;
722
- },
723
- "Sets service name after insertion"
724
- )
725
717
  ).emits("meta.service_registry.service_inserted").emitsOnFail("meta.service_registry.service_insertion_failed");
726
718
  this.insertServiceInstanceTask = CadenzaService.createCadenzaDBInsertTask(
727
719
  "serviceInstance",
@@ -811,7 +803,7 @@ var ServiceRegistry = class _ServiceRegistry {
811
803
  if (isBrowser) {
812
804
  CadenzaService.createMetaTask("Prepare for signal sync", () => {
813
805
  return {};
814
- }).doAfter(this.fullSyncTask).then(
806
+ }).then(
815
807
  CadenzaService.createCadenzaDBQueryTask("signal_registry", {
816
808
  fields: ["name"],
817
809
  filter: {
@@ -2758,7 +2750,7 @@ var DatabaseController = class _DatabaseController {
2758
2750
  if (field.generated)
2759
2751
  def += ` GENERATED ALWAYS AS ${field.generated.toUpperCase()} STORED`;
2760
2752
  if (field.references)
2761
- def += ` REFERENCES ${field.references} ON DELETE ${field.onDelete || "DO NOTHING"}`;
2753
+ def += ` REFERENCES ${field.references} ON DELETE ${field.onDelete || "CASCADE"}`;
2762
2754
  if (field.encrypted) def += " ENCRYPTED";
2763
2755
  if (field.constraints?.check) {
2764
2756
  def += ` CHECK (${field.constraints.check})`;
@@ -3308,6 +3300,7 @@ var DatabaseController = class _DatabaseController {
3308
3300
  if (!data || Array.isArray(data) && data.length === 0) {
3309
3301
  return { errored: true, __error: "No data provided for insert" };
3310
3302
  }
3303
+ let resultContext = {};
3311
3304
  const client = transaction ? await this.getClient() : this.dbClient;
3312
3305
  try {
3313
3306
  if (transaction) await client.query("BEGIN");
@@ -3360,24 +3353,32 @@ var DatabaseController = class _DatabaseController {
3360
3353
  );
3361
3354
  if (transaction) await client.query("COMMIT");
3362
3355
  const resultRows = this.toCamelCase(result.rows);
3363
- return {
3356
+ resultContext = {
3364
3357
  [`${camelCase(tableName)}${isBatch ? "s" : ""}`]: isBatch ? resultRows : resultRows[0],
3365
3358
  rowCount: result.rowCount,
3366
3359
  __success: true
3367
3360
  };
3368
3361
  } catch (error) {
3369
- if (transaction) await client.query("ROLLBACK");
3370
- return {
3371
- ...context,
3372
- errored: true,
3373
- __error: `Insert failed: ${error.message}`,
3374
- __success: false
3375
- };
3362
+ if (error.message.includes("violates unique constraint")) {
3363
+ resultContext = {
3364
+ [`${camelCase(tableName)}`]: null,
3365
+ __success: false
3366
+ };
3367
+ } else {
3368
+ if (transaction) await client.query("ROLLBACK");
3369
+ resultContext = {
3370
+ ...context,
3371
+ errored: true,
3372
+ __error: `Insert failed: ${error.message}`,
3373
+ __success: false
3374
+ };
3375
+ }
3376
3376
  } finally {
3377
3377
  if (transaction && client) {
3378
3378
  client.release();
3379
3379
  }
3380
3380
  }
3381
+ return resultContext;
3381
3382
  }
3382
3383
  /**
3383
3384
  * Updates a database table with the provided data and filter conditions.
@@ -3399,6 +3400,7 @@ var DatabaseController = class _DatabaseController {
3399
3400
  if (!data || Object.keys(data).length === 0) {
3400
3401
  return { errored: true, __error: "No data provided for update" };
3401
3402
  }
3403
+ let resultContext = {};
3402
3404
  const client = transaction ? await this.getClient() : this.dbClient;
3403
3405
  try {
3404
3406
  if (transaction) await client.query("BEGIN");
@@ -3431,19 +3433,20 @@ var DatabaseController = class _DatabaseController {
3431
3433
  if (transaction) await client.query("COMMIT");
3432
3434
  const rows = this.toCamelCase(result.rows);
3433
3435
  if (rows.length === 0) {
3434
- return {
3436
+ resultContext = {
3435
3437
  sql,
3436
3438
  params,
3437
3439
  __success: false
3438
3440
  };
3441
+ } else {
3442
+ resultContext = {
3443
+ [`${camelCase(tableName)}`]: rows[0],
3444
+ __success: true
3445
+ };
3439
3446
  }
3440
- return {
3441
- [`${camelCase(tableName)}`]: rows[0],
3442
- __success: true
3443
- };
3444
3447
  } catch (error) {
3445
3448
  if (transaction) await client.query("ROLLBACK");
3446
- return {
3449
+ resultContext = {
3447
3450
  ...context,
3448
3451
  errored: true,
3449
3452
  __error: `Update failed: ${error.message}`,
@@ -3454,6 +3457,7 @@ var DatabaseController = class _DatabaseController {
3454
3457
  client.release();
3455
3458
  }
3456
3459
  }
3460
+ return resultContext;
3457
3461
  }
3458
3462
  /**
3459
3463
  * Deletes a record from the specified database table based on the given filter criteria.
@@ -3470,6 +3474,7 @@ var DatabaseController = class _DatabaseController {
3470
3474
  if (Object.keys(filter).length === 0) {
3471
3475
  return { errored: true, __error: "No filter provided for delete" };
3472
3476
  }
3477
+ let resultContext = {};
3473
3478
  const client = transaction ? await this.getClient() : this.dbClient;
3474
3479
  try {
3475
3480
  if (transaction) await client.query("BEGIN");
@@ -3479,13 +3484,13 @@ var DatabaseController = class _DatabaseController {
3479
3484
  const result = await client.query(sql, params);
3480
3485
  if (transaction) await client.query("COMMIT");
3481
3486
  const rows = this.toCamelCase(result.rows);
3482
- return {
3487
+ resultContext = {
3483
3488
  [`${camelCase(tableName)}`]: rows[0],
3484
3489
  __success: true
3485
3490
  };
3486
3491
  } catch (error) {
3487
3492
  if (transaction) await client.query("ROLLBACK");
3488
- return {
3493
+ resultContext = {
3489
3494
  errored: true,
3490
3495
  __error: `Delete failed: ${error.message}`,
3491
3496
  __errors: { delete: error.message },
@@ -3496,6 +3501,7 @@ var DatabaseController = class _DatabaseController {
3496
3501
  client.release();
3497
3502
  }
3498
3503
  }
3504
+ return resultContext;
3499
3505
  }
3500
3506
  /**
3501
3507
  * Constructs a SQL WHERE clause based on the provided filter object.
@@ -3588,9 +3594,7 @@ var DatabaseController = class _DatabaseController {
3588
3594
  let result;
3589
3595
  if (op.subOperation === "insert") {
3590
3596
  const resolvedData = await this.resolveNestedData(op.data, op.table);
3591
- const sql = `INSERT INTO ${op.table} (${Object.keys(resolvedData).join(", ")}) VALUES (${Object.values(
3592
- resolvedData
3593
- ).map((_, i) => `$${i + 1}`).join(", ")}) ON CONFLICT DO NOTHING RETURNING ${op.return ?? "*"}`;
3597
+ const sql = `INSERT INTO ${op.table} (${Object.keys(resolvedData).map((k) => snakeCase(k)).join(", ")}) VALUES (${Object.values(resolvedData).map((_, i) => `$${i + 1}`).join(", ")}) ON CONFLICT DO NOTHING RETURNING ${op.return ?? "*"}`;
3594
3598
  result = await client.query(sql, Object.values(resolvedData));
3595
3599
  result = result.rows[0]?.[op.return ?? "uuid"];
3596
3600
  if (!result) {
@@ -3757,6 +3761,7 @@ var GraphSyncController = class _GraphSyncController {
3757
3761
  this.splitRoutinesTask = CadenzaService.createMetaTask(
3758
3762
  "Split routines for registration",
3759
3763
  (ctx, emit) => {
3764
+ console.log("SPLITTING ROUTINES FOR REGISTRATION");
3760
3765
  const { routines } = ctx;
3761
3766
  if (!routines) return;
3762
3767
  for (const routine of routines) {
@@ -3798,6 +3803,7 @@ var GraphSyncController = class _GraphSyncController {
3798
3803
  uuid: CadenzaService.serviceRegistry.serviceInstanceId
3799
3804
  }
3800
3805
  });
3806
+ CadenzaService.log("Synced resources...");
3801
3807
  }
3802
3808
  ).attachSignal(
3803
3809
  "global.meta.sync_controller.routine_added",
@@ -3821,8 +3827,7 @@ var GraphSyncController = class _GraphSyncController {
3821
3827
  isGlobal,
3822
3828
  domain,
3823
3829
  action,
3824
- isMeta,
3825
- serviceName: CadenzaService.serviceRegistry.serviceName
3830
+ isMeta
3826
3831
  }
3827
3832
  };
3828
3833
  }
@@ -3847,6 +3852,7 @@ var GraphSyncController = class _GraphSyncController {
3847
3852
  this.splitTasksForRegistration = CadenzaService.createMetaTask(
3848
3853
  "Split tasks for registration",
3849
3854
  function* (ctx) {
3855
+ console.log("SPLITTING TASKS FOR REGISTRATION");
3850
3856
  const tasks = ctx.tasks;
3851
3857
  for (const task of tasks) {
3852
3858
  if (task.registered) continue;
@@ -4113,7 +4119,9 @@ var GraphSyncController = class _GraphSyncController {
4113
4119
  )
4114
4120
  );
4115
4121
  CadenzaService.throttle("sync_controller.sync_tick", { __syncing: true }, 12e4);
4116
- CadenzaService.schedule("meta.sync_requested", { __syncing: true }, 2e3);
4122
+ if (this.isCadenzaDBReady) {
4123
+ CadenzaService.schedule("meta.sync_requested", { __syncing: true }, 2e3);
4124
+ }
4117
4125
  }
4118
4126
  };
4119
4127
 
@@ -4465,7 +4473,8 @@ var CadenzaService = class {
4465
4473
  options.isMeta = true;
4466
4474
  const name = `Transmit signal: ${signalName} to ${serviceName}`;
4467
4475
  if (this.get(name)) {
4468
- throw new Error(`Task '${name}' already exists`);
4476
+ console.log("Signal transmission task already exists", name);
4477
+ return;
4469
4478
  }
4470
4479
  return new SignalTransmissionTask(
4471
4480
  name,
@@ -4731,13 +4740,19 @@ var CadenzaService = class {
4731
4740
  __isDatabase: options.isDatabase
4732
4741
  };
4733
4742
  if (options.cadenzaDB?.connect) {
4734
- this.createEphemeralMetaTask("Create service", async (_, emit) => {
4743
+ this.createEphemeralMetaTask("Create service", async (context, emit) => {
4735
4744
  emit("meta.create_service_requested", initContext);
4736
4745
  }).doOn("meta.fetch.handshake_complete");
4737
4746
  } else {
4738
4747
  this.emit("meta.create_service_requested", initContext);
4748
+ this.createMetaTask("Create signal transmission for sync", (ctx) => {
4749
+ this.createSignalTransmissionTask(
4750
+ "global.meta.cadenza_db.gathered_sync_data",
4751
+ ctx.serviceName
4752
+ );
4753
+ }).doOn("meta.rest.handshake");
4739
4754
  }
4740
- this.createEphemeralMetaTask("Handle service setup completion", () => {
4755
+ this.createMetaTask("Handle service setup completion", () => {
4741
4756
  GraphMetadataController.instance;
4742
4757
  GraphSyncController.instance.isCadenzaDBReady = !!options.cadenzaDB?.connect;
4743
4758
  GraphSyncController.instance.init();
@@ -4804,24 +4819,9 @@ var CadenzaService = class {
4804
4819
  databaseName: options.databaseName,
4805
4820
  options
4806
4821
  });
4807
- this.createEphemeralMetaTask("Set database connection", () => {
4808
- if (options.cadenzaDB?.connect) {
4809
- this.createEphemeralMetaTask("Insert database service", (_, emit) => {
4810
- emit("global.meta.created_database_service", {
4811
- data: {
4812
- service_name: name,
4813
- description,
4814
- schema,
4815
- is_meta: options.isMeta
4816
- }
4817
- });
4818
- this.log("Database service created", {
4819
- name,
4820
- isMeta: options.isMeta
4821
- });
4822
- }).doOn("meta.service_registry.service_inserted");
4823
- } else {
4824
- this.emit("global.meta.created_database_service", {
4822
+ this.createMetaTask("Set database connection", () => {
4823
+ this.createMetaTask("Insert database service", (_, emit) => {
4824
+ emit("global.meta.created_database_service", {
4825
4825
  data: {
4826
4826
  service_name: name,
4827
4827
  description,
@@ -4833,7 +4833,7 @@ var CadenzaService = class {
4833
4833
  name,
4834
4834
  isMeta: options.isMeta
4835
4835
  });
4836
- }
4836
+ }).doOn("meta.service_registry.service_inserted");
4837
4837
  this.createCadenzaService(name, description, options);
4838
4838
  }).doOn("meta.database.setup_done");
4839
4839
  }