@open-mercato/cli 0.7.1-develop.7185.1.0f280ef1f1 → 0.7.1-develop.7186.1.6e080a5017

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 (91) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/AGENTS.md +1 -1
  3. package/dist/agentic/guides/module-facts.json +136 -136
  4. package/dist/agentic/guides/module-facts.v2.json +136 -136
  5. package/dist/agentic/guides/modules/ai_assistant/index.md +1 -1
  6. package/dist/agentic/guides/modules/api_docs/index.md +1 -1
  7. package/dist/agentic/guides/modules/api_keys/index.md +1 -1
  8. package/dist/agentic/guides/modules/attachments/index.md +1 -1
  9. package/dist/agentic/guides/modules/audit_logs/index.md +1 -1
  10. package/dist/agentic/guides/modules/auth/index.md +1 -1
  11. package/dist/agentic/guides/modules/business_rules/index.md +1 -1
  12. package/dist/agentic/guides/modules/catalog/index.md +1 -1
  13. package/dist/agentic/guides/modules/channel_apns/index.md +1 -1
  14. package/dist/agentic/guides/modules/channel_discord/index.md +1 -1
  15. package/dist/agentic/guides/modules/channel_expo/index.md +1 -1
  16. package/dist/agentic/guides/modules/channel_fcm/index.md +1 -1
  17. package/dist/agentic/guides/modules/channel_gmail/index.md +1 -1
  18. package/dist/agentic/guides/modules/channel_imap/index.md +1 -1
  19. package/dist/agentic/guides/modules/channel_resend/index.md +1 -1
  20. package/dist/agentic/guides/modules/channel_ses/index.md +1 -1
  21. package/dist/agentic/guides/modules/checkout/index.md +1 -1
  22. package/dist/agentic/guides/modules/communication_channels/index.md +1 -1
  23. package/dist/agentic/guides/modules/configs/index.md +1 -1
  24. package/dist/agentic/guides/modules/content/index.md +1 -1
  25. package/dist/agentic/guides/modules/currencies/index.md +1 -1
  26. package/dist/agentic/guides/modules/customer_accounts/index.md +1 -1
  27. package/dist/agentic/guides/modules/customers/index.md +1 -1
  28. package/dist/agentic/guides/modules/dashboards/index.md +1 -1
  29. package/dist/agentic/guides/modules/data_sync/index.md +1 -1
  30. package/dist/agentic/guides/modules/design_system/index.md +1 -1
  31. package/dist/agentic/guides/modules/devices/index.md +1 -1
  32. package/dist/agentic/guides/modules/dictionaries/index.md +1 -1
  33. package/dist/agentic/guides/modules/directory/index.md +1 -1
  34. package/dist/agentic/guides/modules/documents/index.md +1 -1
  35. package/dist/agentic/guides/modules/entities/index.md +1 -1
  36. package/dist/agentic/guides/modules/eudr/index.md +1 -1
  37. package/dist/agentic/guides/modules/events/index.md +1 -1
  38. package/dist/agentic/guides/modules/feature_toggles/index.md +1 -1
  39. package/dist/agentic/guides/modules/gateway_stripe/index.md +1 -1
  40. package/dist/agentic/guides/modules/generators/index.md +1 -1
  41. package/dist/agentic/guides/modules/inbox_ops/index.md +1 -1
  42. package/dist/agentic/guides/modules/integrations/index.md +1 -1
  43. package/dist/agentic/guides/modules/messages/index.md +1 -1
  44. package/dist/agentic/guides/modules/notifications/index.md +1 -1
  45. package/dist/agentic/guides/modules/onboarding/index.md +1 -1
  46. package/dist/agentic/guides/modules/payment_gateways/index.md +1 -1
  47. package/dist/agentic/guides/modules/perspectives/index.md +1 -1
  48. package/dist/agentic/guides/modules/phone_calls/index.md +1 -1
  49. package/dist/agentic/guides/modules/planner/index.md +1 -1
  50. package/dist/agentic/guides/modules/portal/index.md +1 -1
  51. package/dist/agentic/guides/modules/progress/index.md +1 -1
  52. package/dist/agentic/guides/modules/push_notifications/index.md +1 -1
  53. package/dist/agentic/guides/modules/query_index/index.md +1 -1
  54. package/dist/agentic/guides/modules/record_locks/index.md +1 -1
  55. package/dist/agentic/guides/modules/resources/index.md +1 -1
  56. package/dist/agentic/guides/modules/sales/index.md +1 -1
  57. package/dist/agentic/guides/modules/scheduler/index.md +1 -1
  58. package/dist/agentic/guides/modules/search/index.md +1 -1
  59. package/dist/agentic/guides/modules/security/index.md +1 -1
  60. package/dist/agentic/guides/modules/shipping_carriers/index.md +1 -1
  61. package/dist/agentic/guides/modules/sso/index.md +1 -1
  62. package/dist/agentic/guides/modules/staff/index.md +1 -1
  63. package/dist/agentic/guides/modules/storage_s3/index.md +1 -1
  64. package/dist/agentic/guides/modules/sync_akeneo/index.md +1 -1
  65. package/dist/agentic/guides/modules/sync_excel/index.md +1 -1
  66. package/dist/agentic/guides/modules/system_status_overlays/index.md +1 -1
  67. package/dist/agentic/guides/modules/tillio/index.md +1 -1
  68. package/dist/agentic/guides/modules/translations/index.md +1 -1
  69. package/dist/agentic/guides/modules/warranty_claims/index.md +1 -1
  70. package/dist/agentic/guides/modules/webhooks/index.md +1 -1
  71. package/dist/agentic/guides/modules/wms/index.md +1 -1
  72. package/dist/agentic/guides/modules/workflows/index.md +1 -1
  73. package/dist/agentic/guides/reference-module-facts.json +1 -1
  74. package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +1 -0
  75. package/dist/agentic/guides/upstream/manifest.json +2 -2
  76. package/dist/lib/generate-watch-structure.js +1 -0
  77. package/dist/lib/generate-watch-structure.js.map +2 -2
  78. package/dist/lib/generators/module-registry.js +45 -0
  79. package/dist/lib/generators/module-registry.js.map +2 -2
  80. package/dist/lib/module-runtimes.js +99 -0
  81. package/dist/lib/module-runtimes.js.map +7 -0
  82. package/dist/mercato.js +9 -0
  83. package/dist/mercato.js.map +2 -2
  84. package/package.json +6 -6
  85. package/src/__tests__/module-runtimes.test.ts +267 -0
  86. package/src/lib/__tests__/generate-watch-structure.test.ts +18 -0
  87. package/src/lib/generate-watch-structure.ts +1 -0
  88. package/src/lib/generators/__tests__/registry-variant-parity.test.ts +28 -1
  89. package/src/lib/generators/module-registry.ts +52 -0
  90. package/src/lib/module-runtimes.ts +195 -0
  91. package/src/mercato.ts +20 -0
@@ -0,0 +1,99 @@
1
+ import {
2
+ moduleRuntimeAppliesTo
3
+ } from "@open-mercato/shared/modules/runtime";
4
+ const DEFAULT_START_TIMEOUT_MS = 3e4;
5
+ const DEFAULT_STOP_TIMEOUT_MS = 3e4;
6
+ const START_TIMEOUT_ENV_VAR = "OM_MODULE_RUNTIME_START_TIMEOUT_MS";
7
+ const STOP_TIMEOUT_ENV_VAR = "OM_MODULE_RUNTIME_STOP_TIMEOUT_MS";
8
+ class ModuleRuntimeTimeoutError extends Error {
9
+ constructor(moduleId, phase, timeoutMs) {
10
+ super(`Module "${moduleId}" did not ${phase} within ${timeoutMs}ms.`);
11
+ this.name = "ModuleRuntimeTimeoutError";
12
+ }
13
+ }
14
+ function resolveTimeoutMs(env, name, fallbackMs, log) {
15
+ const raw = env[name];
16
+ if (raw == null || raw.trim() === "") return fallbackMs;
17
+ const parsed = Number(raw);
18
+ if (!Number.isFinite(parsed) || parsed <= 0) {
19
+ log(`[runtime] ignoring ${name}="${raw}": expected a positive number of milliseconds, using ${fallbackMs}ms`);
20
+ return fallbackMs;
21
+ }
22
+ return parsed;
23
+ }
24
+ async function withTimeout(work, timeoutMs, onTimeout) {
25
+ let timer;
26
+ try {
27
+ return await Promise.race([
28
+ work,
29
+ new Promise((_resolve, reject) => {
30
+ timer = setTimeout(() => reject(onTimeout()), timeoutMs);
31
+ })
32
+ ]);
33
+ } finally {
34
+ if (timer) clearTimeout(timer);
35
+ }
36
+ }
37
+ async function startModuleRuntimes(options) {
38
+ const log = options.log ?? ((message) => console.log(message));
39
+ const env = options.env ?? process.env;
40
+ const startTimeoutMs = options.startTimeoutMs ?? resolveTimeoutMs(env, START_TIMEOUT_ENV_VAR, DEFAULT_START_TIMEOUT_MS, log);
41
+ const stopTimeoutMs = options.stopTimeoutMs ?? resolveTimeoutMs(env, STOP_TIMEOUT_ENV_VAR, DEFAULT_STOP_TIMEOUT_MS, log);
42
+ const controller = new AbortController();
43
+ const started = [];
44
+ const applicable = options.modules.filter((m) => Boolean(m.runtime) && moduleRuntimeAppliesTo(m.runtime, options.role)).sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);
45
+ const stopStarted = async () => {
46
+ controller.abort();
47
+ for (const entry of [...started].reverse()) {
48
+ if (!entry.handle) continue;
49
+ try {
50
+ await withTimeout(
51
+ Promise.resolve(entry.handle.stop()),
52
+ stopTimeoutMs,
53
+ () => new ModuleRuntimeTimeoutError(entry.id, "stop", stopTimeoutMs)
54
+ );
55
+ log(`[runtime] stopped "${entry.id}"`);
56
+ } catch (error) {
57
+ log(`[runtime] "${entry.id}" failed to stop: ${error instanceof Error ? error.message : String(error)}`);
58
+ }
59
+ }
60
+ started.length = 0;
61
+ };
62
+ for (const module of applicable) {
63
+ const startedAt = Date.now();
64
+ const starting = (async () => module.runtime.start({ container: options.container, role: options.role, signal: controller.signal }))();
65
+ try {
66
+ const handle = await withTimeout(
67
+ starting,
68
+ startTimeoutMs,
69
+ () => new ModuleRuntimeTimeoutError(module.id, "start", startTimeoutMs)
70
+ );
71
+ started.push({ id: module.id, handle });
72
+ log(`[runtime] started "${module.id}" (${options.role}, ${Date.now() - startedAt}ms)`);
73
+ } catch (error) {
74
+ if (error instanceof ModuleRuntimeTimeoutError) {
75
+ void starting.then((handle) => handle?.stop()).catch(() => {
76
+ });
77
+ }
78
+ await stopStarted();
79
+ throw error;
80
+ }
81
+ }
82
+ let stopping = null;
83
+ return {
84
+ started: started.map((entry) => entry.id),
85
+ stop: () => stopping ??= stopStarted()
86
+ };
87
+ }
88
+ function isProductionBuildPhase(env = process.env) {
89
+ return env.NEXT_PHASE === "phase-production-build";
90
+ }
91
+ export {
92
+ DEFAULT_START_TIMEOUT_MS,
93
+ DEFAULT_STOP_TIMEOUT_MS,
94
+ START_TIMEOUT_ENV_VAR,
95
+ STOP_TIMEOUT_ENV_VAR,
96
+ isProductionBuildPhase,
97
+ startModuleRuntimes
98
+ };
99
+ //# sourceMappingURL=module-runtimes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/module-runtimes.ts"],
4
+ "sourcesContent": ["// Starting and stopping the module runtimes declared by `runtime.ts` (SPEC-072).\n//\n// Kept out of mercato.ts so the contract can be tested directly: the ordering, the failure\n// semantics, the shutdown and both timeouts are the whole substance of this hook, and none of\n// them are reachable through a CLI command in a test.\n\nimport type { AppContainer } from '@open-mercato/shared/lib/di/container'\nimport {\n moduleRuntimeAppliesTo,\n type ModuleRuntime,\n type ModuleRuntimeHandle,\n type ModuleRuntimeRole,\n} from '@open-mercato/shared/modules/runtime'\n\nexport const DEFAULT_START_TIMEOUT_MS = 30_000\nexport const DEFAULT_STOP_TIMEOUT_MS = 30_000\n\nexport const START_TIMEOUT_ENV_VAR = 'OM_MODULE_RUNTIME_START_TIMEOUT_MS'\nexport const STOP_TIMEOUT_ENV_VAR = 'OM_MODULE_RUNTIME_STOP_TIMEOUT_MS'\n\nexport type ModuleRuntimeCarrier = { id: string; runtime?: ModuleRuntime }\n\nexport type StartModuleRuntimesOptions = {\n modules: ModuleRuntimeCarrier[]\n container: AppContainer\n role: ModuleRuntimeRole\n /** One line per start and stop. Defaults to console. */\n log?: (message: string) => void\n /** Defaults to `OM_MODULE_RUNTIME_START_TIMEOUT_MS`, then 30s. */\n startTimeoutMs?: number\n /** Defaults to `OM_MODULE_RUNTIME_STOP_TIMEOUT_MS`, then 30s. */\n stopTimeoutMs?: number\n /** Where the timeout overrides are read from. Defaults to `process.env`. */\n env?: NodeJS.ProcessEnv\n}\n\nexport type StartedModuleRuntimes = {\n /** Module ids whose runtime is running, in start order. */\n started: string[]\n /** Aborts the shared signal, then stops each runtime in reverse start order. Idempotent. */\n stop(): Promise<void>\n}\n\nclass ModuleRuntimeTimeoutError extends Error {\n constructor(moduleId: string, phase: 'start' | 'stop', timeoutMs: number) {\n super(`Module \"${moduleId}\" did not ${phase} within ${timeoutMs}ms.`)\n this.name = 'ModuleRuntimeTimeoutError'\n }\n}\n\n/**\n * Reads a timeout override, falling back to `fallbackMs` when it is unset or not a usable number.\n *\n * A start timeout is fatal by design (contract \u00A73), so an operator whose runtime legitimately needs\n * longer than the default \u2014 acquiring a lease, waiting on a broker \u2014 needs a supported way to say\n * so rather than a worker that exits non-zero on every boot. A malformed value falls back loudly:\n * refusing to start over a typo in a tuning knob would be worse than the default it replaces.\n */\nfunction resolveTimeoutMs(\n env: NodeJS.ProcessEnv,\n name: string,\n fallbackMs: number,\n log: (message: string) => void,\n): number {\n const raw = env[name]\n if (raw == null || raw.trim() === '') return fallbackMs\n const parsed = Number(raw)\n if (!Number.isFinite(parsed) || parsed <= 0) {\n log(`[runtime] ignoring ${name}=\"${raw}\": expected a positive number of milliseconds, using ${fallbackMs}ms`)\n return fallbackMs\n }\n return parsed\n}\n\n/**\n * Rejects if `work` outlives `timeoutMs`.\n *\n * The timer is always cleared, including on the winning path: an uncleared timer keeps the event\n * loop alive, so a CLI command that finished its work would hang until the timeout elapsed \u2014 the\n * kind of bug that only shows up as \"the process takes 30 seconds to exit\".\n */\nasync function withTimeout<T>(work: Promise<T>, timeoutMs: number, onTimeout: () => Error): Promise<T> {\n let timer: NodeJS.Timeout | undefined\n try {\n return await Promise.race([\n work,\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(onTimeout()), timeoutMs)\n }),\n ])\n } finally {\n if (timer) clearTimeout(timer)\n }\n}\n\n/**\n * Starts every module runtime that applies to this role, once.\n *\n * A throwing or timing-out `start` is fatal: the runtimes already started are stopped, and the\n * error is rethrown for the caller to exit on. A process that came up without a runtime it was\n * supposed to have looks healthy while doing nothing, which is worse than not coming up.\n */\nexport async function startModuleRuntimes(options: StartModuleRuntimesOptions): Promise<StartedModuleRuntimes> {\n const log = options.log ?? ((message: string) => console.log(message))\n const env = options.env ?? process.env\n const startTimeoutMs = options.startTimeoutMs\n ?? resolveTimeoutMs(env, START_TIMEOUT_ENV_VAR, DEFAULT_START_TIMEOUT_MS, log)\n const stopTimeoutMs = options.stopTimeoutMs\n ?? resolveTimeoutMs(env, STOP_TIMEOUT_ENV_VAR, DEFAULT_STOP_TIMEOUT_MS, log)\n\n const controller = new AbortController()\n const started: Array<{ id: string; handle: ModuleRuntimeHandle | void }> = []\n\n // Sorted by module id so a failure is reproducible rather than dependent on registry order.\n // Compared by code point rather than `localeCompare`, which depends on the host's default locale\n // and ICU build \u2014 \"reproducible\" must not mean \"on machines with the same locale\".\n //\n // No dependency graph on purpose: a module that needs another module's runtime should depend on\n // its service through DI, which already expresses that and already detects cycles.\n const applicable = options.modules\n .filter((m): m is ModuleRuntimeCarrier & { runtime: ModuleRuntime } =>\n Boolean(m.runtime) && moduleRuntimeAppliesTo(m.runtime as ModuleRuntime, options.role))\n .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))\n\n const stopStarted = async (): Promise<void> => {\n controller.abort()\n for (const entry of [...started].reverse()) {\n if (!entry.handle) continue\n try {\n await withTimeout(\n Promise.resolve(entry.handle.stop()),\n stopTimeoutMs,\n () => new ModuleRuntimeTimeoutError(entry.id, 'stop', stopTimeoutMs),\n )\n log(`[runtime] stopped \"${entry.id}\"`)\n } catch (error) {\n // A shutdown that cannot finish must not become a shutdown that never finishes: report and\n // carry on to the next runtime, so one stuck module cannot hold the process open.\n log(`[runtime] \"${entry.id}\" failed to stop: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n started.length = 0\n }\n\n for (const module of applicable) {\n const startedAt = Date.now()\n // Called through an async wrapper so a `start` that throws synchronously rejects rather than\n // escaping the try below, which would skip stopping the runtimes already started.\n const starting = (async () =>\n module.runtime.start({ container: options.container, role: options.role, signal: controller.signal }))()\n try {\n const handle = await withTimeout(\n starting,\n startTimeoutMs,\n () => new ModuleRuntimeTimeoutError(module.id, 'start', startTimeoutMs),\n )\n started.push({ id: module.id, handle })\n log(`[runtime] started \"${module.id}\" (${options.role}, ${Date.now() - startedAt}ms)`)\n } catch (error) {\n // A timed-out `start` keeps running: its handle was never pushed to `started`, so shutdown\n // would not reach it. Trail the promise and release whatever it eventually hands back \u2014 and\n // swallow a late rejection, which would otherwise surface as an unhandled rejection long\n // after the error below has already been reported.\n if (error instanceof ModuleRuntimeTimeoutError) {\n void starting\n .then((handle) => handle?.stop())\n .catch(() => {})\n }\n await stopStarted()\n throw error\n }\n }\n\n let stopping: Promise<void> | null = null\n return {\n started: started.map((entry) => entry.id),\n stop: () => (stopping ??= stopStarted()),\n }\n}\n\n/**\n * True when this process is a Next production build.\n *\n * A build evaluates application code and must not acquire brokers, sockets or leases \u2014 and must\n * certainly not briefly own work it cannot finish. Hosts have been carrying this check by hand;\n * it belongs with the runner.\n *\n * At its only call site today \u2014 `mercato queue worker --all` \u2014 it is always false: `NEXT_PHASE` is\n * set by Next, not by a worker process. It guards the entry that matters once the `server` role\n * lands, where module code really is evaluated during `next build`; it is here so that entry\n * inherits the check rather than reinventing it.\n */\nexport function isProductionBuildPhase(env: NodeJS.ProcessEnv = process.env): boolean {\n return env.NEXT_PHASE === 'phase-production-build'\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/dist/mercato.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { registerWorkerShutdownHook, runWorker } from "@open-mercato/queue/worker";
2
+ import { isProductionBuildPhase, startModuleRuntimes } from "./lib/module-runtimes.js";
2
3
  import { getCliModules, hasCliModules, registerCliModules } from "./registry.js";
3
4
  import { parseBooleanToken } from "@open-mercato/shared/lib/boolean";
4
5
  import { getSslConfig } from "@open-mercato/shared/lib/db/ssl";
@@ -1382,6 +1383,14 @@ async function run(argv = process.argv) {
1382
1383
  });
1383
1384
  console.log("[worker] Local scheduler started in the shared worker process.");
1384
1385
  }
1386
+ if (!isProductionBuildPhase()) {
1387
+ const runtimes = await startModuleRuntimes({
1388
+ modules: getCliModules(),
1389
+ container: await createRequestContainer(),
1390
+ role: "worker"
1391
+ });
1392
+ if (runtimes.started.length > 0) registerWorkerShutdownHook(() => runtimes.stop());
1393
+ }
1385
1394
  console.log("[worker] All workers started. Press Ctrl+C to stop");
1386
1395
  await new Promise(() => {
1387
1396
  });