@voyant-travel/hono 0.133.0 → 0.134.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/app.d.ts +2 -3
- package/dist/app.js +2 -84
- package/dist/bundle.d.ts +2 -14
- package/dist/openapi.d.ts +1 -2
- package/dist/openapi.js +1 -2
- package/dist/types.d.ts +0 -69
- package/dist/types.js +0 -5
- package/package.json +5 -7
- package/dist/app-workflows.d.ts +0 -30
- package/dist/app-workflows.js +0 -115
package/dist/app.d.ts
CHANGED
|
@@ -34,9 +34,8 @@ export interface ModuleMount {
|
|
|
34
34
|
/**
|
|
35
35
|
* App handle returned alongside the Hono instance. Carries `ready()` for
|
|
36
36
|
* headless / sibling-process deployments that need to fire the lazy
|
|
37
|
-
* bootstrap before the first HTTP request
|
|
38
|
-
*
|
|
39
|
-
* manifest registration kick off without traffic.
|
|
37
|
+
* bootstrap before the first HTTP request. Resident hosts and tests call this
|
|
38
|
+
* so selected runtime registration completes without waiting for traffic.
|
|
40
39
|
*
|
|
41
40
|
* Returned via the augmented Hono instance: `app.ready` is attached
|
|
42
41
|
* directly so the existing call sites (which destructure / pass `app`
|
package/dist/app.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// agent-quality: file-size exception — app.ts is the framework composition root;
|
|
2
2
|
// splitting it is intentional follow-up work, not part of voyant#2114.
|
|
3
3
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
4
|
-
import { createContainer, createEventBus, createQueryRunner
|
|
4
|
+
import { createContainer, createEventBus, createQueryRunner } from "@voyant-travel/core";
|
|
5
5
|
import { createLinkServiceFactory } from "@voyant-travel/db/links";
|
|
6
6
|
import { assembleAnonymousPaths, assembleOptionalCustomerAuthPaths } from "./anonymous-paths.js";
|
|
7
|
-
import { containerToServiceResolver, makeFrameworkLogger, wireWorkflowRuntime, } from "./app-workflows.js";
|
|
8
7
|
import { composeAuthAugmentations } from "./auth-augmentation.js";
|
|
9
8
|
import { expandApiBundles, isLazyApiBundle, } from "./bundle.js";
|
|
10
9
|
import { assembleClientAuthenticatedRoutes, matchesClientAuthenticatedRoute, } from "./client-authenticated-routes.js";
|
|
@@ -137,48 +136,6 @@ export function mountApp(config) {
|
|
|
137
136
|
for (const sub of expanded?.subscribers ?? []) {
|
|
138
137
|
eventBus.subscribe(sub.event, sub.handler, { inline: sub.inline ?? false });
|
|
139
138
|
}
|
|
140
|
-
// ---- Workflow runtime wiring (synchronous setup; manifest registration
|
|
141
|
-
// + EventBus forwarder run inside the lazy bootstrap below) ----
|
|
142
|
-
//
|
|
143
|
-
// We collect `workflows` + `eventFilters` from every module and plugin
|
|
144
|
-
// here so the failure mode for "duplicate workflow id across modules"
|
|
145
|
-
// surfaces at construction time (per architecture doc §18, the workflow
|
|
146
|
-
// runtime is fail-closed).
|
|
147
|
-
const collectedWorkflows = [];
|
|
148
|
-
const collectedFilters = [];
|
|
149
|
-
function collectModuleRuntimeDescriptors(modules) {
|
|
150
|
-
for (const mod of modules) {
|
|
151
|
-
if (mod.module.workflows)
|
|
152
|
-
collectedWorkflows.push(...mod.module.workflows);
|
|
153
|
-
if (mod.module.eventFilters)
|
|
154
|
-
collectedFilters.push(...mod.module.eventFilters);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function collectPluginRuntimeDescriptors(plugins) {
|
|
158
|
-
for (const plugin of plugins) {
|
|
159
|
-
if (plugin.workflows)
|
|
160
|
-
collectedWorkflows.push(...plugin.workflows);
|
|
161
|
-
if (plugin.eventFilters)
|
|
162
|
-
collectedFilters.push(...plugin.eventFilters);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
function assertUniqueWorkflowIds() {
|
|
166
|
-
if (!config.workflows || collectedWorkflows.length === 0)
|
|
167
|
-
return;
|
|
168
|
-
const seen = new Map();
|
|
169
|
-
for (const wf of collectedWorkflows) {
|
|
170
|
-
const existing = seen.get(wf.id);
|
|
171
|
-
if (existing && existing !== wf) {
|
|
172
|
-
throw new Error(`[voyant] duplicate workflow id "${wf.id}" registered by multiple modules/plugins. ` +
|
|
173
|
-
`Workflow ids must be unique across the app — use a module-scoped prefix ` +
|
|
174
|
-
`(e.g. "${wf.id.includes(".") ? wf.id : `<module>.${wf.id}`}").`);
|
|
175
|
-
}
|
|
176
|
-
seen.set(wf.id, wf);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
collectModuleRuntimeDescriptors(allModules);
|
|
180
|
-
collectPluginRuntimeDescriptors(eagerPlugins);
|
|
181
|
-
assertUniqueWorkflowIds();
|
|
182
139
|
const txModuleNames = new Set();
|
|
183
140
|
const txRequiringModules = [];
|
|
184
141
|
const txPrefixes = [...(config.dbTransactionalPaths ?? [])];
|
|
@@ -273,8 +230,6 @@ export function mountApp(config) {
|
|
|
273
230
|
for (const sub of lazyExpanded.subscribers) {
|
|
274
231
|
eventBus.subscribe(sub.event, sub.handler, { inline: sub.inline ?? false });
|
|
275
232
|
}
|
|
276
|
-
collectModuleRuntimeDescriptors(lazyExpanded.modules);
|
|
277
|
-
collectPluginRuntimeDescriptors(pending);
|
|
278
233
|
addTransactionalSurfaces(lazyExpanded.modules, lazyExpanded.extensions);
|
|
279
234
|
}
|
|
280
235
|
async function ensureBootstrapLazyPluginsExpanded() {
|
|
@@ -293,47 +248,12 @@ export function mountApp(config) {
|
|
|
293
248
|
}
|
|
294
249
|
await lazyPluginExpansionPromise;
|
|
295
250
|
}
|
|
296
|
-
// Workflow driver construction is **deferred** to the lazy bootstrap
|
|
297
|
-
// path so callers whose driver options come from `env.*` bindings can
|
|
298
|
-
// pass a function-of-bindings shape. Node / InMemory users usually
|
|
299
|
-
// return a direct factory from that function.
|
|
300
|
-
let workflowDriver;
|
|
301
251
|
let bootstrapPromise = null;
|
|
302
252
|
function ensureRuntimeBootstrapped(bindings) {
|
|
303
253
|
if (!bootstrapPromise) {
|
|
304
254
|
bootstrapPromise = (async () => {
|
|
305
255
|
const ctx = { bindings, container, eventBus };
|
|
306
256
|
await ensureBootstrapLazyPluginsExpanded();
|
|
307
|
-
assertUniqueWorkflowIds();
|
|
308
|
-
// ---- Workflow runtime FIRST — fail-closed manifest registration
|
|
309
|
-
// and EventBus forwarder must be in place before any module
|
|
310
|
-
// bootstrap can emit. Otherwise a `module.bootstrap` that
|
|
311
|
-
// emits an event during its own bootstrap would route through
|
|
312
|
-
// a bus with no workflow forwarder yet, silently losing the
|
|
313
|
-
// event. Per architecture doc §21.22 + reviewer feedback P2.3.
|
|
314
|
-
if (config.workflows) {
|
|
315
|
-
// `driver` is always a function-of-bindings (per
|
|
316
|
-
// VoyantWorkflowsConfig — see types.ts + reviewer feedback P2.1).
|
|
317
|
-
// Node / InMemory users wrap with `() => createXxxDriver({...})`.
|
|
318
|
-
// Managed-cloud users can derive a forwarding driver from `env`.
|
|
319
|
-
// We invoke with bindings, then the resulting DriverFactory
|
|
320
|
-
// with framework deps.
|
|
321
|
-
const factoryDeps = {
|
|
322
|
-
services: containerToServiceResolver(container),
|
|
323
|
-
logger: makeFrameworkLogger(config.logger),
|
|
324
|
-
};
|
|
325
|
-
const factory = config.workflows.driver(bindings);
|
|
326
|
-
workflowDriver = factory(factoryDeps);
|
|
327
|
-
await wireWorkflowRuntime({
|
|
328
|
-
modules: allModules.map((m) => m.module),
|
|
329
|
-
collectedWorkflows,
|
|
330
|
-
collectedFilters,
|
|
331
|
-
driver: workflowDriver,
|
|
332
|
-
environment: config.workflows.environment ?? "development",
|
|
333
|
-
projectId: config.workflows.projectId ?? "default",
|
|
334
|
-
eventBus,
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
257
|
// Run each bootstrap in isolation — a single failing plugin/module/extension
|
|
338
258
|
// must not poison the cached promise and kill the whole app's request pipeline.
|
|
339
259
|
const runIsolated = async (label, fn) => {
|
|
@@ -521,10 +441,8 @@ export function mountApp(config) {
|
|
|
521
441
|
app.use("*", db(dbSource, { requiresTransactionalDb: txRequiringModules, basePath: config.basePath }));
|
|
522
442
|
app.use("*", async (c, next) => {
|
|
523
443
|
// Bootstrap only after auth has admitted the request. Rejected requests
|
|
524
|
-
// must not initialize package runtimes
|
|
444
|
+
// must not initialize package runtimes.
|
|
525
445
|
await ensureRuntimeBootstrapped(c.env);
|
|
526
|
-
if (workflowDriver)
|
|
527
|
-
c.set("workflowDriver", workflowDriver);
|
|
528
446
|
return next();
|
|
529
447
|
});
|
|
530
448
|
if (createRequestLinkService) {
|
package/dist/bundle.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BootstrapHandler,
|
|
1
|
+
import type { BootstrapHandler, LinkDefinition, Subscriber } from "@voyant-travel/core";
|
|
2
2
|
import type { ApiExtension, ApiModule } from "./module.js";
|
|
3
3
|
/**
|
|
4
4
|
* Reusable server API contribution surface.
|
|
@@ -37,17 +37,6 @@ export interface ApiBundle {
|
|
|
37
37
|
* these into the assembled anonymous allow-list.
|
|
38
38
|
*/
|
|
39
39
|
anonymous?: string[];
|
|
40
|
-
/**
|
|
41
|
-
* Workflows contributed by the plugin. Mirrors the `Plugin.workflows`
|
|
42
|
-
* field in `@voyant-travel/core` — collected at `createApp()` boot and
|
|
43
|
-
* registered with the configured workflow driver.
|
|
44
|
-
*/
|
|
45
|
-
workflows?: readonly WorkflowDescriptor[];
|
|
46
|
-
/**
|
|
47
|
-
* Event filters contributed by the plugin. Mirrors
|
|
48
|
-
* `Plugin.eventFilters` in `@voyant-travel/core`.
|
|
49
|
-
*/
|
|
50
|
-
eventFilters?: readonly EventFilterDescriptor[];
|
|
51
40
|
}
|
|
52
41
|
declare const LAZY_API_BUNDLE: unique symbol;
|
|
53
42
|
/**
|
|
@@ -89,8 +78,7 @@ export interface LazyApiBundle {
|
|
|
89
78
|
/**
|
|
90
79
|
* Load this bundle during app bootstrap instead of waiting for a declared
|
|
91
80
|
* route matcher. Set this for lazy bundles that contribute subscribers,
|
|
92
|
-
*
|
|
93
|
-
* bundle-owned route is hit.
|
|
81
|
+
* container services, or bootstraps needed before a bundle-owned route is hit.
|
|
94
82
|
*/
|
|
95
83
|
loadOnBootstrap?: boolean;
|
|
96
84
|
/** Loads and constructs the real bundle. Memoized by `mountApp`. */
|
package/dist/openapi.d.ts
CHANGED
|
@@ -141,8 +141,7 @@ export declare function buildModulePathOwnership(mounts: readonly ModuleMount[],
|
|
|
141
141
|
* admin/storefront path (voyant#2733).
|
|
142
142
|
*
|
|
143
143
|
* Uses the ownership map as the authoritative module owner, falling back to the
|
|
144
|
-
* path's own segment for anything the manifest doesn't claim
|
|
145
|
-
* `additionalRoutes` mounts like the operator's workflow-runs admin surface).
|
|
144
|
+
* path's own segment for anything the manifest doesn't claim.
|
|
146
145
|
* The full surface is therefore partitioned exactly: every `/v1/admin/*` and
|
|
147
146
|
* `/v1/public/*` path lands in exactly one module document. Non-surface routes
|
|
148
147
|
* (`/v1/<name>` webhooks, legacy `/v1/*`) live only in the aggregate, as before.
|
package/dist/openapi.js
CHANGED
|
@@ -220,8 +220,7 @@ export async function buildModulePathOwnership(mounts, options) {
|
|
|
220
220
|
* admin/storefront path (voyant#2733).
|
|
221
221
|
*
|
|
222
222
|
* Uses the ownership map as the authoritative module owner, falling back to the
|
|
223
|
-
* path's own segment for anything the manifest doesn't claim
|
|
224
|
-
* `additionalRoutes` mounts like the operator's workflow-runs admin surface).
|
|
223
|
+
* path's own segment for anything the manifest doesn't claim.
|
|
225
224
|
* The full surface is therefore partitioned exactly: every `/v1/admin/*` and
|
|
226
225
|
* `/v1/public/*` path lands in exactly one module document. Non-surface routes
|
|
227
226
|
* (`/v1/<name>` webhooks, legacy `/v1/*`) live only in the aggregate, as before.
|
package/dist/types.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { Actor, VoyantVariables as CoreVoyantVariables, EventBus, LinkDefin
|
|
|
2
2
|
import type { SelectApikey } from "@voyant-travel/db/schema/iam";
|
|
3
3
|
import type { AccessCatalog } from "@voyant-travel/types/api-keys";
|
|
4
4
|
import type { KVStore } from "@voyant-travel/utils/cache";
|
|
5
|
-
import type { DriverFactory } from "@voyant-travel/workflows/driver";
|
|
6
5
|
import type { NeonHttpDatabase } from "drizzle-orm/neon-http";
|
|
7
6
|
import type { NeonDatabase as NeonWsDatabase } from "drizzle-orm/neon-serverless";
|
|
8
7
|
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
@@ -47,8 +46,6 @@ export type VoyantVariables = CoreVoyantVariables & {
|
|
|
47
46
|
link?: LinkService;
|
|
48
47
|
/** Shared cross-module query runtime, when the app wires one in. */
|
|
49
48
|
query?: VoyantQueryRuntime;
|
|
50
|
-
/** Optional workflow driver surfaced to HTTP routes after lazy app bootstrap. */
|
|
51
|
-
workflowDriver?: import("@voyant-travel/workflows/driver").WorkflowDriver;
|
|
52
49
|
};
|
|
53
50
|
/** Handler contract for application-authored Hono API routes. */
|
|
54
51
|
export type VoyantRouteHandler<TBindings extends VoyantBindings = VoyantBindings> = Handler<{
|
|
@@ -291,17 +288,6 @@ export interface VoyantAppConfig<TBindings extends VoyantBindings = VoyantBindin
|
|
|
291
288
|
* individual policies.
|
|
292
289
|
*/
|
|
293
290
|
rateLimit?: false | import("./middleware/rate-limit.js").RateLimitConfig;
|
|
294
|
-
/**
|
|
295
|
-
* Workflow runtime configuration. When set, `createApp()` collects
|
|
296
|
-
* `module.workflows` + `module.eventFilters` (plus the same fields
|
|
297
|
-
* from plugins), invokes `workflows.driver` with framework deps, and
|
|
298
|
-
* — inside the lazy bootstrap path — registers the manifest with the
|
|
299
|
-
* driver and installs an EventBus forwarder that routes emitted
|
|
300
|
-
* events to `driver.ingestEvent(...)`.
|
|
301
|
-
*
|
|
302
|
-
* See `docs/architecture/workflows-runtime-architecture.md` §6, §18.
|
|
303
|
-
*/
|
|
304
|
-
workflows?: VoyantWorkflowsConfig;
|
|
305
291
|
/**
|
|
306
292
|
* Admin API capability metadata, served at `GET /v1/admin/_meta/capabilities`
|
|
307
293
|
* so clients (the admin SDK) can discover what this deployment supports —
|
|
@@ -325,58 +311,3 @@ export interface VoyantAppConfig<TBindings extends VoyantBindings = VoyantBindin
|
|
|
325
311
|
};
|
|
326
312
|
additionalRoutes?: (app: Hono<any>) => void;
|
|
327
313
|
}
|
|
328
|
-
/**
|
|
329
|
-
* Workflow runtime configuration block. The driver is resolved at boot
|
|
330
|
-
* time (inside the lazy bootstrap path), after framework deps and —
|
|
331
|
-
* crucially — after runtime bindings are available.
|
|
332
|
-
*
|
|
333
|
-
* `driver` is **always** a function-of-bindings: `(env) => DriverFactory`.
|
|
334
|
-
* This unambiguous shape works for local node runtimes and managed-cloud
|
|
335
|
-
* forwarding drivers:
|
|
336
|
-
*
|
|
337
|
-
* **Node / InMemory** — wrap your direct factory:
|
|
338
|
-
*
|
|
339
|
-
* workflows: {
|
|
340
|
-
* driver: () => createStandaloneDriver({ db }),
|
|
341
|
-
* }
|
|
342
|
-
*
|
|
343
|
-
* **Managed Cloud forwarding** — pull credentials off `env`:
|
|
344
|
-
*
|
|
345
|
-
* workflows: {
|
|
346
|
-
* driver: (env) => () => createCloudWorkflowDriver({
|
|
347
|
-
* baseUrl: env.VOYANT_CLOUD_WORKFLOWS_URL,
|
|
348
|
-
* triggerToken: env.VOYANT_CLOUD_WORKFLOW_TRIGGER_TOKEN,
|
|
349
|
-
* appSlug: env.VOYANT_CLOUD_APP_SLUG,
|
|
350
|
-
* environment: env.VOYANT_CLOUD_ENVIRONMENT,
|
|
351
|
-
* }),
|
|
352
|
-
* }
|
|
353
|
-
*
|
|
354
|
-
* The single shape avoids ambiguous "is this a factory or a
|
|
355
|
-
* factory-of-factories?" heuristics. See architecture doc §6.3 +
|
|
356
|
-
* reviewer feedback P2.1.
|
|
357
|
-
*/
|
|
358
|
-
export interface VoyantWorkflowsConfig<TBindings = unknown> {
|
|
359
|
-
/**
|
|
360
|
-
* Function-of-bindings that returns a `DriverFactory`. Resolved
|
|
361
|
-
* lazily with `c.env` once bindings are available, then invoked
|
|
362
|
-
* with `{ services, logger }` to produce the driver.
|
|
363
|
-
*/
|
|
364
|
-
driver: (bindings: TBindings) => DriverFactory;
|
|
365
|
-
/**
|
|
366
|
-
* Environment the manifest registers under. Defaults to `"development"`.
|
|
367
|
-
* Workflow filters are environment-scoped (production manifests don't
|
|
368
|
-
* see preview events and vice versa) per architecture doc §21.10.
|
|
369
|
-
*/
|
|
370
|
-
environment?: "production" | "preview" | "development";
|
|
371
|
-
/**
|
|
372
|
-
* Project / tenant identifier baked into the manifest. Single-tenant
|
|
373
|
-
* runtimes leave this unset (defaults to `"default"`). Multi-tenant
|
|
374
|
-
* deployments override per-app via voyant-cloud's wrapper layer.
|
|
375
|
-
*/
|
|
376
|
-
projectId?: string;
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Structural shape of a `DriverFactory` from `@voyant-travel/workflows/driver`.
|
|
380
|
-
* The SDK package's concrete `DriverFactory` satisfies this via TS
|
|
381
|
-
* structural compat (architecture doc §21.19).
|
|
382
|
-
*/
|
package/dist/types.js
CHANGED
|
@@ -22,8 +22,3 @@ export function resolveDbFactoryResult(value) {
|
|
|
22
22
|
const dispose = dbClientDispose(value);
|
|
23
23
|
return dispose ? { db: value, dispose } : { db: value };
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Structural shape of a `DriverFactory` from `@voyant-travel/workflows/driver`.
|
|
27
|
-
* The SDK package's concrete `DriverFactory` satisfies this via TS
|
|
28
|
-
* structural compat (architecture doc §21.19).
|
|
29
|
-
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyant-travel/hono",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.134.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -130,17 +130,15 @@
|
|
|
130
130
|
"drizzle-orm": "^0.45.2",
|
|
131
131
|
"hono": "^4.12.27",
|
|
132
132
|
"zod": "^4.4.3",
|
|
133
|
-
"@voyant-travel/core": "^0.
|
|
134
|
-
"@voyant-travel/db": "^0.
|
|
135
|
-
"@voyant-travel/types": "^0.109.8",
|
|
133
|
+
"@voyant-travel/core": "^0.132.0",
|
|
134
|
+
"@voyant-travel/db": "^0.118.1",
|
|
136
135
|
"@voyant-travel/utils": "^0.109.0",
|
|
137
|
-
"@voyant-travel/
|
|
136
|
+
"@voyant-travel/types": "^0.109.9"
|
|
138
137
|
},
|
|
139
138
|
"devDependencies": {
|
|
140
139
|
"typescript": "^6.0.3",
|
|
141
140
|
"vitest": "^4.1.9",
|
|
142
|
-
"@voyant-travel/voyant-typescript-config": "^0.1.0"
|
|
143
|
-
"@voyant-travel/workflows-orchestrator": "^0.122.18"
|
|
141
|
+
"@voyant-travel/voyant-typescript-config": "^0.1.0"
|
|
144
142
|
},
|
|
145
143
|
"files": [
|
|
146
144
|
"dist"
|
package/dist/app-workflows.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { EventEnvelope, EventFilterDescriptor, Module, ModuleContainer, WorkflowDescriptor } from "@voyant-travel/core";
|
|
2
|
-
import type { WorkflowDriver } from "@voyant-travel/workflows/driver";
|
|
3
|
-
import type { VoyantAppConfig } from "./types.js";
|
|
4
|
-
export interface WireWorkflowRuntimeArgs {
|
|
5
|
-
modules: ReadonlyArray<Module>;
|
|
6
|
-
collectedWorkflows: ReadonlyArray<WorkflowDescriptor>;
|
|
7
|
-
collectedFilters: ReadonlyArray<EventFilterDescriptor>;
|
|
8
|
-
driver: WorkflowDriver;
|
|
9
|
-
environment: "production" | "preview" | "development";
|
|
10
|
-
projectId: string;
|
|
11
|
-
eventBus: {
|
|
12
|
-
subscribe(event: string, handler: (e: EventEnvelope) => Promise<void> | void): unknown;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Build the manifest, register it with the driver, and install a single
|
|
17
|
-
* EventBus subscriber per unique eventType seen across the manifest's filters.
|
|
18
|
-
*/
|
|
19
|
-
export declare function wireWorkflowRuntime(args: WireWorkflowRuntimeArgs): Promise<void>;
|
|
20
|
-
/**
|
|
21
|
-
* Adapt the framework's `ModuleContainer` to a read-only `ServiceResolver`.
|
|
22
|
-
*/
|
|
23
|
-
export declare function containerToServiceResolver(container: ModuleContainer): {
|
|
24
|
-
resolve<T>(name: string): T;
|
|
25
|
-
has(name: string): boolean;
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Adapt the framework's optional `LoggerProvider` to the workflow driver logger.
|
|
29
|
-
*/
|
|
30
|
-
export declare function makeFrameworkLogger(loggerProvider: VoyantAppConfig["logger"] | undefined): (level: "debug" | "info" | "warn" | "error", msg: string, data?: object) => void;
|
package/dist/app-workflows.js
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
function toManifestWorkflowDescriptor(wf) {
|
|
2
|
-
const candidate = wf;
|
|
3
|
-
return candidate.config ? { id: wf.id, config: candidate.config } : { id: wf.id };
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Build the manifest, register it with the driver, and install a single
|
|
7
|
-
* EventBus subscriber per unique eventType seen across the manifest's filters.
|
|
8
|
-
*/
|
|
9
|
-
export async function wireWorkflowRuntime(args) {
|
|
10
|
-
// Keep app composition importable before workspace packages are built. The
|
|
11
|
-
// workflow implementation is needed only when a configured app boots.
|
|
12
|
-
const { buildManifest } = await import("@voyant-travel/workflows/events");
|
|
13
|
-
// The descriptors collected from modules + plugins use core's structural
|
|
14
|
-
// types (`{ id, eventType }` only - see `EventFilterDescriptor` in core);
|
|
15
|
-
// the manifest builder needs the runtime shape with `.manifest` populated.
|
|
16
|
-
// Validate before casting so a contract-violating plugin fails loudly here
|
|
17
|
-
// instead of crashing on `entry.manifest.id` deep inside the sort.
|
|
18
|
-
const filterEntries = [];
|
|
19
|
-
for (const entry of args.collectedFilters) {
|
|
20
|
-
const candidate = entry;
|
|
21
|
-
if (!candidate.manifest || typeof candidate.manifest.id !== "string") {
|
|
22
|
-
throw new Error(`[voyant] event filter "${entry.id}" (event "${entry.eventType}") is missing the runtime ` +
|
|
23
|
-
`\`manifest\` field. Filters must be produced via \`trigger.on(eventName, { ... })\` from ` +
|
|
24
|
-
`@voyant-travel/workflows - the public EventFilterDescriptor is the structural minimum, but ` +
|
|
25
|
-
`createApp() needs the manifest payload to register with the driver.`);
|
|
26
|
-
}
|
|
27
|
-
filterEntries.push({
|
|
28
|
-
id: candidate.manifest.id,
|
|
29
|
-
eventType: candidate.manifest.eventType,
|
|
30
|
-
manifest: candidate.manifest,
|
|
31
|
-
declaration: { target: { id: candidate.manifest.targetWorkflowId } },
|
|
32
|
-
targetWorkflowId: candidate.manifest.targetWorkflowId,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
const manifest = await buildManifest({
|
|
36
|
-
projectId: args.projectId,
|
|
37
|
-
environment: args.environment,
|
|
38
|
-
workflows: args.collectedWorkflows.map(toManifestWorkflowDescriptor),
|
|
39
|
-
eventFilters: filterEntries,
|
|
40
|
-
});
|
|
41
|
-
await args.driver.registerManifest({
|
|
42
|
-
environment: args.environment,
|
|
43
|
-
manifest,
|
|
44
|
-
});
|
|
45
|
-
// Install one EventBus subscriber per unique eventType. Each subscriber
|
|
46
|
-
// forwards the envelope through `driver.ingestEvent(...)`, which routes
|
|
47
|
-
// through the same predicate/mapper machinery the HTTP ingest path uses.
|
|
48
|
-
const eventTypes = new Set(filterEntries.map((f) => f.manifest.eventType));
|
|
49
|
-
for (const eventType of eventTypes) {
|
|
50
|
-
args.eventBus.subscribe(eventType, async (envelope) => {
|
|
51
|
-
const stamped = ensureMetadataEventId(envelope);
|
|
52
|
-
// Let ingest failures propagate: the EventBus catches every subscriber
|
|
53
|
-
// throw (the emitter and sibling handlers stay unaffected per its
|
|
54
|
-
// fire-and-forget contract) AND routes it through `onSubscriberError`, so
|
|
55
|
-
// a misbehaving driver / network glitch is both logged and reported via
|
|
56
|
-
// the framework reporter — instead of being swallowed here (RFC #1553).
|
|
57
|
-
await args.driver.ingestEvent({
|
|
58
|
-
environment: args.environment,
|
|
59
|
-
envelope: stamped,
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Adapt the framework's `ModuleContainer` to a read-only `ServiceResolver`.
|
|
66
|
-
*/
|
|
67
|
-
export function containerToServiceResolver(container) {
|
|
68
|
-
return {
|
|
69
|
-
resolve(name) {
|
|
70
|
-
return container.resolve(name);
|
|
71
|
-
},
|
|
72
|
-
has(name) {
|
|
73
|
-
return container.has(name);
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Adapt the framework's optional `LoggerProvider` to the workflow driver logger.
|
|
79
|
-
*/
|
|
80
|
-
export function makeFrameworkLogger(loggerProvider) {
|
|
81
|
-
void loggerProvider;
|
|
82
|
-
return (level, msg, data) => {
|
|
83
|
-
const fn = level === "error"
|
|
84
|
-
? console.error
|
|
85
|
-
: level === "warn"
|
|
86
|
-
? console.warn
|
|
87
|
-
: level === "debug"
|
|
88
|
-
? console.debug
|
|
89
|
-
: console.log;
|
|
90
|
-
if (data !== undefined)
|
|
91
|
-
fn(`[voyant] ${msg}`, data);
|
|
92
|
-
else
|
|
93
|
-
fn(`[voyant] ${msg}`);
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
function ensureMetadataEventId(envelope) {
|
|
97
|
-
const metadata = envelope.metadata;
|
|
98
|
-
if (metadata !== undefined &&
|
|
99
|
-
metadata !== null &&
|
|
100
|
-
typeof metadata === "object" &&
|
|
101
|
-
typeof metadata.eventId === "string" &&
|
|
102
|
-
(metadata.eventId.length ?? 0) > 0) {
|
|
103
|
-
return envelope;
|
|
104
|
-
}
|
|
105
|
-
const eventId = `evt_${Date.now().toString(36)}_${Math.floor(Math.random() * 1_000_000)
|
|
106
|
-
.toString(36)
|
|
107
|
-
.padStart(4, "0")}`;
|
|
108
|
-
return {
|
|
109
|
-
...envelope,
|
|
110
|
-
metadata: {
|
|
111
|
-
...(metadata ?? {}),
|
|
112
|
-
eventId,
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
}
|