@cadenza.io/service 1.4.1 → 1.5.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.
package/dist/index.d.mts CHANGED
@@ -140,11 +140,14 @@ interface ServiceInstanceDescriptor {
140
140
  isBlocked: boolean;
141
141
  health: AnyObject;
142
142
  exposed: boolean;
143
+ clientCreated?: boolean;
143
144
  }
144
145
  interface DeputyDescriptor {
145
- __serviceName: string;
146
- __remoteRoutineName: string;
147
- __localTaskName: string;
146
+ serviceName: string;
147
+ remoteRoutineName?: string;
148
+ signalName?: string;
149
+ localTaskName: string;
150
+ communicationType: string;
148
151
  }
149
152
  declare class ServiceRegistry {
150
153
  private static _instance;
package/dist/index.d.ts CHANGED
@@ -140,11 +140,14 @@ interface ServiceInstanceDescriptor {
140
140
  isBlocked: boolean;
141
141
  health: AnyObject;
142
142
  exposed: boolean;
143
+ clientCreated?: boolean;
143
144
  }
144
145
  interface DeputyDescriptor {
145
- __serviceName: string;
146
- __remoteRoutineName: string;
147
- __localTaskName: string;
146
+ serviceName: string;
147
+ remoteRoutineName?: string;
148
+ signalName?: string;
149
+ localTaskName: string;
150
+ communicationType: string;
148
151
  }
149
152
  declare class ServiceRegistry {
150
153
  private static _instance;
package/dist/index.js CHANGED
@@ -203,10 +203,11 @@ var DeputyTask = class extends import_core.Task {
203
203
  this.remoteRoutineName = remoteRoutineName;
204
204
  this.serviceName = serviceName;
205
205
  this.emit("meta.deputy.created", {
206
- __localTaskName: this.name,
207
- __localTaskVersion: this.version,
208
- __remoteRoutineName: this.remoteRoutineName,
209
- __serviceName: this.serviceName
206
+ localTaskName: this.name,
207
+ localTaskVersion: this.version,
208
+ remoteRoutineName: this.remoteRoutineName,
209
+ serviceName: this.serviceName,
210
+ communicationType: "delegation"
210
211
  });
211
212
  }
212
213
  /**
@@ -333,6 +334,7 @@ var ServiceRegistry = class _ServiceRegistry {
333
334
  this.handleInstanceUpdateTask = CadenzaService.createMetaTask(
334
335
  "Handle Instance Update",
335
336
  (ctx, emit) => {
337
+ var _a2;
336
338
  const { serviceInstance } = ctx;
337
339
  const { id, serviceName, address, port, exposed } = serviceInstance;
338
340
  if (!this.instances.has(serviceName))
@@ -343,13 +345,32 @@ var ServiceRegistry = class _ServiceRegistry {
343
345
  Object.assign(existing, serviceInstance);
344
346
  } else {
345
347
  if (this.deputies.has(serviceName)) {
348
+ const communicationTypes = Array.from(
349
+ new Set(
350
+ (_a2 = this.deputies.get(serviceName).map((d) => d.communicationType)) != null ? _a2 : []
351
+ )
352
+ );
346
353
  emit("meta.service_registry.dependee_registered", {
347
- __serviceName: serviceName,
348
- __serviceInstanceId: id,
349
- __serviceAddress: address,
350
- __servicePort: port,
351
- __protocol: exposed ? "https" : "http"
354
+ serviceName,
355
+ serviceInstanceId: id,
356
+ serviceAddress: address,
357
+ servicePort: port,
358
+ protocol: exposed ? "https" : "http",
359
+ communicationTypes
352
360
  });
361
+ serviceInstance.clientCreated = true;
362
+ for (const instance of this.instances.get(serviceName)) {
363
+ if (instance.clientCreated) continue;
364
+ instance.clientCreated = true;
365
+ emit("meta.service_registry.dependee_registered", {
366
+ serviceName,
367
+ serviceInstanceId: id,
368
+ serviceAddress: address,
369
+ servicePort: port,
370
+ protocol: exposed ? "https" : "http",
371
+ communicationTypes
372
+ });
373
+ }
353
374
  }
354
375
  instances.push(serviceInstance);
355
376
  }
@@ -402,7 +423,7 @@ var ServiceRegistry = class _ServiceRegistry {
402
423
  const { serviceInstances } = ctx;
403
424
  if (!serviceInstances) return;
404
425
  for (const serviceInstance of serviceInstances) {
405
- yield serviceInstance;
426
+ yield { serviceInstance };
406
427
  }
407
428
  }).then(this.handleInstanceUpdateTask)
408
429
  );
@@ -446,21 +467,15 @@ var ServiceRegistry = class _ServiceRegistry {
446
467
  this.handleDeputyRegistrationTask = CadenzaService.createMetaTask(
447
468
  "Handle Deputy Registration",
448
469
  (ctx, emit) => {
449
- const { __serviceName } = ctx;
450
- this.deputies.set(__serviceName, {
451
- __serviceName,
452
- __remoteRoutineName: ctx.__remoteRoutineName,
453
- __localTaskName: ctx.__localTaskName
470
+ const { serviceName } = ctx;
471
+ if (!this.deputies.has(serviceName)) this.deputies.set(serviceName, []);
472
+ this.deputies.get(serviceName).push({
473
+ serviceName,
474
+ remoteRoutineName: ctx.remoteRoutineName,
475
+ signalName: ctx.signalName,
476
+ localTaskName: ctx.localTaskName,
477
+ communicationType: ctx.communicationType
454
478
  });
455
- for (const instance of this.instances.get(__serviceName)) {
456
- emit(`meta.service_registry.dependee_registered:${instance.id}`, {
457
- __serviceName,
458
- __serviceInstanceId: instance.id,
459
- __serviceAddress: instance.address,
460
- __servicePort: instance.port,
461
- __protocol: instance.exposed ? "https" : "http"
462
- });
463
- }
464
479
  }
465
480
  ).doOn("meta.deputy.created");
466
481
  this.getAllInstances = CadenzaService.createMetaTask(
@@ -802,6 +817,13 @@ var SignalTransmissionTask = class extends import_core2.Task {
802
817
  this.isDeputy = true;
803
818
  this.serviceName = serviceName;
804
819
  this.signalName = signalName;
820
+ this.emit("meta.deputy.created", {
821
+ localTaskName: this.name,
822
+ localTaskVersion: this.version,
823
+ serviceName: this.serviceName,
824
+ communicationType: "signal",
825
+ signalName: this.signalName
826
+ });
805
827
  }
806
828
  /**
807
829
  * Triggers the database operation delegation flow via a signal to the meta-layer.
@@ -1072,33 +1094,54 @@ var RestController = class _RestController {
1072
1094
  "Bootstraps the REST server as socket fallback"
1073
1095
  ).doOn("meta.service_registry.service_inserted");
1074
1096
  CadenzaService.createMetaTask(
1075
- "FetchClient",
1076
- (ctx) => {
1097
+ "Setup fetch client",
1098
+ (ctx, emit) => {
1077
1099
  const {
1078
- __serviceName,
1079
- __serviceInstanceId,
1080
- __serviceAddress,
1081
- __servicePort,
1082
- __protocol
1100
+ serviceName,
1101
+ serviceInstanceId,
1102
+ serviceAddress,
1103
+ servicePort,
1104
+ protocol
1083
1105
  } = ctx;
1084
- const port = __protocol === "https" ? 443 : __servicePort;
1085
- const URL = `${__protocol}://${__serviceAddress}:${port}`;
1106
+ const port = protocol === "https" ? 443 : servicePort;
1107
+ const URL = `${protocol}://${serviceAddress}:${port}`;
1086
1108
  CadenzaService.createMetaTask(
1087
1109
  "Send Handshake",
1088
- (ctx2) => __async(null, null, function* () {
1110
+ (ctx2, emit2) => __async(null, null, function* () {
1111
+ var _a2;
1089
1112
  const response = yield (0, import_node_fetch.default)(`${URL}/handshake`, {
1090
1113
  method: "POST",
1091
1114
  body: JSON.stringify(ctx2)
1092
1115
  });
1093
1116
  const result = yield response.json();
1094
- result.__serviceInstanceId = __serviceInstanceId;
1095
- return result;
1117
+ if (result.__status === "error" || result.status !== 200) {
1118
+ throw new Error(
1119
+ (_a2 = result.__error) != null ? _a2 : `Failed to connect to service ${serviceName} ${ctx2.serviceInstanceId}`
1120
+ );
1121
+ }
1122
+ console.log(
1123
+ `Connected to service ${serviceName} ${ctx2.serviceInstanceId}`,
1124
+ result
1125
+ );
1126
+ for (const communicationType of ctx2.communicationTypes) {
1127
+ emit2("meta.fetch.service_communication_established", {
1128
+ serviceInstanceId: ctx2.serviceInstanceId,
1129
+ serviceInstanceClientId: CadenzaService.serviceRegistry.serviceInstanceId,
1130
+ communicationType
1131
+ });
1132
+ }
1096
1133
  }),
1097
- "Sends handshake request"
1098
- ).doOn("meta.fetch.handshake_requested").emits("meta.fetch.handshake_complete");
1134
+ "Sends handshake request",
1135
+ {
1136
+ retryCount: 20,
1137
+ retryDelay: 200,
1138
+ retryDelayMax: 5e3,
1139
+ retryDelayFactor: 1.5
1140
+ }
1141
+ ).doOn(`meta.fetch.handshake_requested:${serviceInstanceId}`).emits("meta.fetch.handshake_complete");
1099
1142
  CadenzaService.createMetaTask(
1100
1143
  "Delegate flow to REST server",
1101
- (ctx2, emit) => __async(null, null, function* () {
1144
+ (ctx2, emit2) => __async(null, null, function* () {
1102
1145
  if (ctx2.__remoteRoutineName === void 0) {
1103
1146
  return;
1104
1147
  }
@@ -1115,18 +1158,18 @@ var RestController = class _RestController {
1115
1158
  errored: true
1116
1159
  }, ctx2), ctx2.__metadata);
1117
1160
  } finally {
1118
- emit(`meta.fetch.delegated:${ctx2.__deputyExecId}`, resultContext);
1161
+ emit2(`meta.fetch.delegated:${ctx2.__deputyExecId}`, resultContext);
1119
1162
  }
1120
1163
  return resultContext;
1121
1164
  }),
1122
1165
  "Sends delegation request"
1123
1166
  ).doOn(
1124
- `meta.service_registry.selected_instance_for_fetch:${__serviceInstanceId}`,
1125
- `meta.service_registry.socket_failed:${__serviceInstanceId}`
1167
+ `meta.service_registry.selected_instance_for_fetch:${serviceInstanceId}`,
1168
+ `meta.service_registry.socket_failed:${serviceInstanceId}`
1126
1169
  ).emitsOnFail("meta.fetch.delegate_failed");
1127
1170
  CadenzaService.createMetaTask(
1128
1171
  "Transmit signal to server",
1129
- (ctx2, emit) => __async(null, null, function* () {
1172
+ (ctx2, emit2) => __async(null, null, function* () {
1130
1173
  if (ctx2.__signalName === void 0) {
1131
1174
  return;
1132
1175
  }
@@ -1138,7 +1181,7 @@ var RestController = class _RestController {
1138
1181
  });
1139
1182
  response = yield response.json();
1140
1183
  if (ctx2.__routineExecId) {
1141
- emit(`meta.fetch.transmitted:${ctx2.__routineExecId}`, response);
1184
+ emit2(`meta.fetch.transmitted:${ctx2.__routineExecId}`, response);
1142
1185
  }
1143
1186
  } catch (e) {
1144
1187
  response = __spreadValues({
@@ -1150,8 +1193,8 @@ var RestController = class _RestController {
1150
1193
  }),
1151
1194
  "Sends signal request"
1152
1195
  ).doOn(
1153
- `meta.service_registry.selected_instance_for_fetch:${__serviceInstanceId}`,
1154
- `meta.signal_controller.remote_signal_registered:${__serviceName}`,
1196
+ `meta.service_registry.selected_instance_for_fetch:${serviceInstanceId}`,
1197
+ `meta.signal_controller.remote_signal_registered:${serviceName}`,
1155
1198
  "meta.signal_controller.wildcard_signal_registered"
1156
1199
  ).emitsOnFail("meta.fetch.signal_transmission_failed");
1157
1200
  CadenzaService.createMetaTask(
@@ -1171,6 +1214,7 @@ var RestController = class _RestController {
1171
1214
  }),
1172
1215
  "Requests status"
1173
1216
  ).doOn("meta.fetch.status_check_requested").emits("meta.fetch.status_checked").emitsOnFail("meta.fetch.status_check_failed");
1217
+ emit(`meta.fetch.handshake_requested:${serviceInstanceId}`, __spreadValues({}, ctx));
1174
1218
  return true;
1175
1219
  },
1176
1220
  "Manages REST client requests as fallback"
@@ -2191,7 +2235,7 @@ var DatabaseController = class _DatabaseController {
2191
2235
  "DatabaseServiceInit",
2192
2236
  [
2193
2237
  // Database health check
2194
- // Create database roll
2238
+ // Create database role
2195
2239
  // Create schema version table
2196
2240
  CadenzaService.createMetaTask(
2197
2241
  "Create database",
@@ -2233,20 +2277,34 @@ var DatabaseController = class _DatabaseController {
2233
2277
  }
2234
2278
  for (const [tableName, table] of Object.entries(schema.tables)) {
2235
2279
  if (!table.fields || typeof table.fields !== "object") {
2280
+ console.log(tableName, "missing fields");
2236
2281
  throw new Error(`Invalid table ${tableName}: missing fields`);
2237
2282
  }
2238
2283
  for (const [fieldName, field] of Object.entries(table.fields)) {
2239
2284
  if (!fieldName.split("").every((c) => /[a-z_]/.test(c))) {
2285
+ console.log(tableName, "field not lowercase", fieldName);
2240
2286
  throw new Error(
2241
2287
  `Invalid field name ${fieldName} for ${tableName}. Field names must only contain lowercase alphanumeric characters and underscores`
2242
2288
  );
2243
2289
  }
2244
2290
  if (!Object.values(SCHEMA_TYPES).includes(field.type)) {
2291
+ console.log(
2292
+ tableName,
2293
+ "field invalid type",
2294
+ fieldName,
2295
+ field.type
2296
+ );
2245
2297
  throw new Error(
2246
2298
  `Invalid type ${field.type} for ${tableName}.${fieldName}`
2247
2299
  );
2248
2300
  }
2249
- if (field.references && !field.references.match(/^[\w]+\.[\w]+$/)) {
2301
+ if (field.references && !field.references.match(/^[\w]+[(\w)]+$/)) {
2302
+ console.log(
2303
+ tableName,
2304
+ "invalid reference",
2305
+ fieldName,
2306
+ field.references
2307
+ );
2250
2308
  throw new Error(
2251
2309
  `Invalid reference ${field.references} for ${tableName}.${fieldName}`
2252
2310
  );
@@ -2256,11 +2314,23 @@ var DatabaseController = class _DatabaseController {
2256
2314
  const triggers = (_a2 = table.customSignals.triggers) == null ? void 0 : _a2[op];
2257
2315
  const emissions = (_b2 = table.customSignals.emissions) == null ? void 0 : _b2[op];
2258
2316
  if (triggers && !Array.isArray(triggers) && typeof triggers !== "object") {
2317
+ console.log(
2318
+ tableName,
2319
+ "invalid triggers",
2320
+ op,
2321
+ triggers
2322
+ );
2259
2323
  throw new Error(
2260
2324
  `Invalid triggers for ${tableName}.${op}`
2261
2325
  );
2262
2326
  }
2263
2327
  if (emissions && !Array.isArray(emissions) && typeof emissions !== "object") {
2328
+ console.log(
2329
+ tableName,
2330
+ "invalid emissions",
2331
+ op,
2332
+ emissions
2333
+ );
2264
2334
  throw new Error(
2265
2335
  `Invalid emissions for ${tableName}.${op}`
2266
2336
  );
@@ -2814,6 +2884,7 @@ CREATE TRIGGER prevent_modification BEFORE UPDATE OR DELETE ON ${tableName} FOR
2814
2884
  return typeof signal === "string" ? signal : signal.signal;
2815
2885
  })) != null ? _d2 : []
2816
2886
  ).emits(defaultSignal);
2887
+ console.log("Created database task", op, tableName);
2817
2888
  }
2818
2889
  };
2819
2890
 
@@ -3161,7 +3232,6 @@ var CadenzaService = class {
3161
3232
  });
3162
3233
  import_core3.default.createEphemeralMetaTask("Initiate controllers", () => {
3163
3234
  GraphMetadataController.instance;
3164
- console.log("META CONTROLLERS INITIATED");
3165
3235
  }).doOn("meta.service_registry.instance_inserted").emits("meta.process_signal_queue_requested");
3166
3236
  this.serviceCreated = true;
3167
3237
  }