@voyant-travel/core 0.109.0
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/LICENSE +201 -0
- package/README.md +48 -0
- package/dist/config.d.ts +204 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +251 -0
- package/dist/config.js.map +1 -0
- package/dist/container.d.ts +20 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +21 -0
- package/dist/container.js.map +1 -0
- package/dist/env.d.ts +29 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +2 -0
- package/dist/env.js.map +1 -0
- package/dist/events.d.ts +177 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +169 -0
- package/dist/events.js.map +1 -0
- package/dist/hooks.d.ts +19 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +33 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/links.d.ts +201 -0
- package/dist/links.d.ts.map +1 -0
- package/dist/links.js +159 -0
- package/dist/links.js.map +1 -0
- package/dist/locking.d.ts +12 -0
- package/dist/locking.d.ts.map +1 -0
- package/dist/locking.js +21 -0
- package/dist/locking.js.map +1 -0
- package/dist/module.d.ts +147 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +2 -0
- package/dist/module.js.map +1 -0
- package/dist/orchestration.d.ts +30 -0
- package/dist/orchestration.d.ts.map +1 -0
- package/dist/orchestration.js +2 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/plugin.d.ts +118 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +65 -0
- package/dist/plugin.js.map +1 -0
- package/dist/query.d.ts +111 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +126 -0
- package/dist/query.js.map +1 -0
- package/dist/registry.d.ts +17 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +31 -0
- package/dist/registry.js.map +1 -0
- package/dist/workflows.d.ts +140 -0
- package/dist/workflows.d.ts.map +1 -0
- package/dist/workflows.js +142 -0
- package/dist/workflows.js.map +1 -0
- package/package.json +103 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"links.js","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ExclusiveExecutionResult<T> = {
|
|
2
|
+
executed: true;
|
|
3
|
+
value: T;
|
|
4
|
+
} | {
|
|
5
|
+
executed: false;
|
|
6
|
+
};
|
|
7
|
+
export interface ExecutionLockManager {
|
|
8
|
+
runExclusive<T>(key: string, task: () => Promise<T>): Promise<ExclusiveExecutionResult<T>>;
|
|
9
|
+
dispose?(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export declare function createInMemoryExecutionLockManager(): ExecutionLockManager;
|
|
12
|
+
//# sourceMappingURL=locking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locking.d.ts","sourceRoot":"","sources":["../src/locking.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAA;CAAE,CAAA;AAE5F,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1F,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAED,wBAAgB,kCAAkC,IAAI,oBAAoB,CAoBzE"}
|
package/dist/locking.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function createInMemoryExecutionLockManager() {
|
|
2
|
+
const activeKeys = new Set();
|
|
3
|
+
return {
|
|
4
|
+
async runExclusive(key, task) {
|
|
5
|
+
if (activeKeys.has(key)) {
|
|
6
|
+
return { executed: false };
|
|
7
|
+
}
|
|
8
|
+
activeKeys.add(key);
|
|
9
|
+
try {
|
|
10
|
+
return {
|
|
11
|
+
executed: true,
|
|
12
|
+
value: await task(),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
activeKeys.delete(key);
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=locking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locking.js","sourceRoot":"","sources":["../src/locking.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,kCAAkC;IAChD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;IAEpC,OAAO;QACL,KAAK,CAAC,YAAY,CAAI,GAAW,EAAE,IAAsB;YACvD,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;YAC5B,CAAC;YAED,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACnB,IAAI,CAAC;gBACH,OAAO;oBACL,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,MAAM,IAAI,EAAE;iBACpB,CAAA;YACH,CAAC;oBAAS,CAAC;gBACT,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACxB,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { ModuleContainer } from "./container.js";
|
|
2
|
+
import type { EventBus } from "./events.js";
|
|
3
|
+
import type { LinkableDefinition } from "./links.js";
|
|
4
|
+
/**
|
|
5
|
+
* Minimum structural shape of a workflow registration as exposed by a module
|
|
6
|
+
* or plugin. Defined here in core so `Module` doesn't have to import the
|
|
7
|
+
* concrete `WorkflowDefinition` from `@voyant-travel/workflows` — that would
|
|
8
|
+
* couple core to the workflows package and risk an import cycle (workflows
|
|
9
|
+
* already depends on core for `ModuleContainer` and similar primitives).
|
|
10
|
+
*
|
|
11
|
+
* `@voyant-travel/workflows`'s concrete `WorkflowDefinition` satisfies this
|
|
12
|
+
* descriptor via TypeScript structural compat. Core treats workflows as
|
|
13
|
+
* opaque beyond `id`; the workflows runtime owns the rest.
|
|
14
|
+
*
|
|
15
|
+
* Same pattern Voyant uses for {@link LinkableDefinition} — the structural
|
|
16
|
+
* contract lives in core, concrete types live in their owning packages.
|
|
17
|
+
*/
|
|
18
|
+
export interface WorkflowDescriptor {
|
|
19
|
+
/** Stable workflow identifier (e.g. `"promotions.bulk-reindex-products"`). */
|
|
20
|
+
readonly id: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Minimum structural shape of an event-filter runtime entry as exposed by a
|
|
24
|
+
* module or plugin. Defined here in core for the same reason as
|
|
25
|
+
* {@link WorkflowDescriptor}.
|
|
26
|
+
*
|
|
27
|
+
* `@voyant-travel/workflows`'s concrete `EventFilterRuntimeEntry` (added in PR2)
|
|
28
|
+
* satisfies this descriptor via structural compat.
|
|
29
|
+
*/
|
|
30
|
+
export interface EventFilterDescriptor {
|
|
31
|
+
/** Filter id, derived from the canonicalized declaration's payloadHash. */
|
|
32
|
+
readonly id: string;
|
|
33
|
+
/** Event name the filter targets (matches `EventEnvelope.name`). */
|
|
34
|
+
readonly eventType: string;
|
|
35
|
+
}
|
|
36
|
+
export interface BootstrapContext<TBindings = unknown> {
|
|
37
|
+
/** Runtime bindings/environment available to the current app/isolate. */
|
|
38
|
+
bindings: TBindings;
|
|
39
|
+
/** Shared app container used for explicit runtime registrations. */
|
|
40
|
+
container: ModuleContainer;
|
|
41
|
+
/** Canonical event bus for the current app runtime. */
|
|
42
|
+
eventBus: EventBus;
|
|
43
|
+
}
|
|
44
|
+
export type BootstrapHandler<TBindings = unknown> = (ctx: BootstrapContext<TBindings>) => Promise<void> | void;
|
|
45
|
+
/**
|
|
46
|
+
* A Voyant module provides domain identity and lifecycle hooks.
|
|
47
|
+
*
|
|
48
|
+
* Transport adapters such as Hono or Next.js are layered on top of this
|
|
49
|
+
* contract instead of being part of core.
|
|
50
|
+
*/
|
|
51
|
+
export interface Module {
|
|
52
|
+
/** Unique module identifier (e.g., "contacts", "bookings") */
|
|
53
|
+
name: string;
|
|
54
|
+
/** Hook handlers keyed by event name (e.g., "contacts.beforeCreate") */
|
|
55
|
+
hooks?: Record<string, (...args: unknown[]) => Promise<void> | void>;
|
|
56
|
+
/**
|
|
57
|
+
* Optional service instance registered in the shared app/runtime container
|
|
58
|
+
* under {@link name}.
|
|
59
|
+
*
|
|
60
|
+
* This is intended for explicit runtime wiring in routes, workflows,
|
|
61
|
+
* subscribers, or bootstrap-time registrations. Modules should prefer links
|
|
62
|
+
* and query for cross-module data, and workflows/orchestration for
|
|
63
|
+
* cross-module behavior, rather than treating the container as their default
|
|
64
|
+
* module-to-module integration surface.
|
|
65
|
+
*/
|
|
66
|
+
service?: unknown;
|
|
67
|
+
/**
|
|
68
|
+
* Optional lazy runtime bootstrap executed once per app/isolate, on the
|
|
69
|
+
* first request where bindings are available.
|
|
70
|
+
*
|
|
71
|
+
* Use this to validate runtime configuration, register app-owned provider
|
|
72
|
+
* instances, or perform other lightweight startup wiring. Do not use it for
|
|
73
|
+
* long-running syncs or scheduled background work.
|
|
74
|
+
*/
|
|
75
|
+
bootstrap?: BootstrapHandler;
|
|
76
|
+
/**
|
|
77
|
+
* Entities this module exposes for cross-module linking via `defineLink`.
|
|
78
|
+
* Keyed by entity name (e.g. `{ person: ..., organization: ... }`).
|
|
79
|
+
*/
|
|
80
|
+
linkable?: Record<string, LinkableDefinition>;
|
|
81
|
+
/**
|
|
82
|
+
* Workflows owned by this module. Collected at `createApp()` boot and
|
|
83
|
+
* registered with the configured workflow driver.
|
|
84
|
+
*
|
|
85
|
+
* Concrete entries are produced by `workflow({ id, run })` in
|
|
86
|
+
* `@voyant-travel/workflows`; the field type here is the structural
|
|
87
|
+
* {@link WorkflowDescriptor} so core stays workflow-agnostic.
|
|
88
|
+
*/
|
|
89
|
+
workflows?: readonly WorkflowDescriptor[];
|
|
90
|
+
/**
|
|
91
|
+
* Event filters owned by this module — declarative bindings of the form
|
|
92
|
+
* `event.name → workflow`, evaluated by the driver's event router at
|
|
93
|
+
* `driver.ingestEvent(...)` time.
|
|
94
|
+
*
|
|
95
|
+
* Concrete entries are produced by `trigger.on(eventName, { ... })` in
|
|
96
|
+
* `@voyant-travel/workflows`; the field type here is the structural
|
|
97
|
+
* {@link EventFilterDescriptor} for the same cycle-avoidance reason as
|
|
98
|
+
* {@link workflows} above.
|
|
99
|
+
*/
|
|
100
|
+
eventFilters?: readonly EventFilterDescriptor[];
|
|
101
|
+
/**
|
|
102
|
+
* Declares that this module's write paths use interactive transactions
|
|
103
|
+
* (`db.transaction(async (tx) => …)`) and therefore require a
|
|
104
|
+
* transaction-capable database adapter at runtime.
|
|
105
|
+
*
|
|
106
|
+
* `createApp()` collects this flag across mounted modules and, on the
|
|
107
|
+
* first request, asserts that the resolved db driver supports
|
|
108
|
+
* interactive transactions. If the resolved driver explicitly reports
|
|
109
|
+
* `dbSupportsTransactions(db) === false` (e.g. `neon-http`), the app
|
|
110
|
+
* throws a clear error naming the offending modules and points at the
|
|
111
|
+
* supported adapters (`createServerlessDbClient` /
|
|
112
|
+
* `createDbClient(url, { adapter: "node" })`).
|
|
113
|
+
*
|
|
114
|
+
* This converts the otherwise-late "No transactions support in
|
|
115
|
+
* neon-http driver" exception thrown on first write into an
|
|
116
|
+
* actionable startup error.
|
|
117
|
+
*/
|
|
118
|
+
requiresTransactionalDb?: boolean;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* A Voyant extension adds hooks to an existing module without modifying
|
|
122
|
+
* its source code.
|
|
123
|
+
*/
|
|
124
|
+
export interface Extension {
|
|
125
|
+
/** Unique extension identifier */
|
|
126
|
+
name: string;
|
|
127
|
+
/** Which module this extension attaches to (e.g., "suppliers") */
|
|
128
|
+
module: string;
|
|
129
|
+
/**
|
|
130
|
+
* Whether this extension's routes run interactive Postgres
|
|
131
|
+
* transactions (`db.transaction(...)`). Extensions mount under their
|
|
132
|
+
* target module's path prefix, so a transacting extension forces the
|
|
133
|
+
* transaction-capable db client onto that module's surface even when
|
|
134
|
+
* the module itself doesn't declare `requiresTransactionalDb` (e.g.
|
|
135
|
+
* catalog-authoring's compose/duplicate routes under
|
|
136
|
+
* `/v1/admin/products`).
|
|
137
|
+
*/
|
|
138
|
+
requiresTransactionalDb?: boolean;
|
|
139
|
+
/** Hook handlers keyed by event name */
|
|
140
|
+
hooks?: Record<string, (...args: unknown[]) => Promise<void> | void>;
|
|
141
|
+
/**
|
|
142
|
+
* Optional lazy runtime bootstrap executed once per app/isolate, on the
|
|
143
|
+
* first request where bindings are available.
|
|
144
|
+
*/
|
|
145
|
+
bootstrap?: BootstrapHandler;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,gBAAgB,CAAC,SAAS,GAAG,OAAO;IACnD,yEAAyE;IACzE,QAAQ,EAAE,SAAS,CAAA;IACnB,oEAAoE;IACpE,SAAS,EAAE,eAAe,CAAA;IAC1B,uDAAuD;IACvD,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED,MAAM,MAAM,gBAAgB,CAAC,SAAS,GAAG,OAAO,IAAI,CAClD,GAAG,EAAE,gBAAgB,CAAC,SAAS,CAAC,KAC7B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;AAEzB;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IAEZ,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;IAEpE;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAE5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IAE7C;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAEzC;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAA;IAE/C;;;;;;;;;;;;;;;;OAgBG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IAEZ,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAA;IAEd;;;;;;;;OAQG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;IAEjC,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;IAEpE;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAA;CAC7B"}
|
package/dist/module.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for enqueueing a background job.
|
|
3
|
+
*/
|
|
4
|
+
export interface JobOptions {
|
|
5
|
+
/** Delay before the job becomes runnable (milliseconds). */
|
|
6
|
+
delayMs?: number;
|
|
7
|
+
/** Number of retry attempts on failure. */
|
|
8
|
+
maxAttempts?: number;
|
|
9
|
+
/** Optional idempotency key for dedupe. */
|
|
10
|
+
idempotencyKey?: string;
|
|
11
|
+
/** Runner-specific options passed through opaquely. */
|
|
12
|
+
runnerOptions?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Abstract durable job runner interface. Implementations live in templates
|
|
16
|
+
* or adapter packages; core never reaches for a specific runtime.
|
|
17
|
+
*
|
|
18
|
+
* Voyant Cloud chooses an edge or node runner per workflow step at deploy
|
|
19
|
+
* time. Templates wire their chosen adapter into the shared app/runtime
|
|
20
|
+
* container as `"jobs"`. Framework code that needs to kick off async work
|
|
21
|
+
* does so via explicit runtime resolution such as
|
|
22
|
+
* `container.resolve<JobRunner>("jobs").enqueue(...)`.
|
|
23
|
+
*/
|
|
24
|
+
export interface JobRunner {
|
|
25
|
+
/** Enqueue a job for durable execution. Returns a runner-assigned job id. */
|
|
26
|
+
enqueue(jobName: string, payload: unknown, options?: JobOptions): Promise<string>;
|
|
27
|
+
/** Schedule a recurring job by cron expression. */
|
|
28
|
+
schedule(jobName: string, cron: string, payload: unknown): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=orchestration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestration.d.ts","sourceRoot":"","sources":["../src/orchestration.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACxC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEjF,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestration.js","sourceRoot":"","sources":["../src/orchestration.ts"],"names":[],"mappings":""}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugins — optional distributable bundles that group modules, extensions,
|
|
3
|
+
* event subscribers, and link definitions into a single unit.
|
|
4
|
+
*
|
|
5
|
+
* A plugin is the unit of "distribution" in Voyant: a customer, vendor, or
|
|
6
|
+
* integrator ships a plugin package and it can be registered alongside core
|
|
7
|
+
* modules without touching the framework itself. It is not the default runtime
|
|
8
|
+
* customization unit — modules, providers, extensions, and workflows should be
|
|
9
|
+
* preferred when a smaller seam fits.
|
|
10
|
+
*
|
|
11
|
+
* Core plugins are transport-agnostic — they contain {@link Module} and
|
|
12
|
+
* {@link Extension} values (no HTTP routes). Transport adapters (such as
|
|
13
|
+
* `@voyant-travel/hono`) layer their own plugin shape on top of this
|
|
14
|
+
* contract to carry route bundles.
|
|
15
|
+
*/
|
|
16
|
+
import type { EventBus, EventHandler, EventMetadata } from "./events.js";
|
|
17
|
+
import type { LinkDefinition } from "./links.js";
|
|
18
|
+
import type { BootstrapHandler, EventFilterDescriptor, Extension, Module, WorkflowDescriptor } from "./module.js";
|
|
19
|
+
/**
|
|
20
|
+
* A single event subscription contributed by a plugin.
|
|
21
|
+
*
|
|
22
|
+
* When the plugin is registered, `handler` is attached to the provided
|
|
23
|
+
* {@link EventBus} for the given `event` name.
|
|
24
|
+
*/
|
|
25
|
+
export interface Subscriber<TData = unknown, TMetadata extends EventMetadata | undefined = EventMetadata | undefined> {
|
|
26
|
+
/** Event name, following `<resource>.<pastTenseAction>` convention. */
|
|
27
|
+
event: string;
|
|
28
|
+
/** Callback invoked when the event is emitted. */
|
|
29
|
+
handler: EventHandler<TData, TMetadata>;
|
|
30
|
+
/**
|
|
31
|
+
* When `true`, the handler completes before `emit()` resolves even on
|
|
32
|
+
* runtimes that defer subscriber work past the HTTP response. Reserve
|
|
33
|
+
* for handlers whose side effects must be read-your-writes visible
|
|
34
|
+
* within the emitting request. Default deferrable.
|
|
35
|
+
*/
|
|
36
|
+
inline?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A transport-agnostic plugin bundle.
|
|
40
|
+
*
|
|
41
|
+
* Plugins contribute any combination of:
|
|
42
|
+
* - {@link Module} values (core domain primitives)
|
|
43
|
+
* - {@link Extension} values (hook attachments to existing modules)
|
|
44
|
+
* - {@link Subscriber} values (event listeners)
|
|
45
|
+
* - {@link LinkDefinition} values (cross-module associations)
|
|
46
|
+
*
|
|
47
|
+
* Transport adapters can intersect this shape with their own fields (see
|
|
48
|
+
* `HonoPlugin` in `@voyant-travel/hono` for the Hono variant).
|
|
49
|
+
*/
|
|
50
|
+
export interface Plugin {
|
|
51
|
+
/** Unique plugin identifier (e.g. "payload-cms", "bokun"). */
|
|
52
|
+
name: string;
|
|
53
|
+
/** Optional version tag for diagnostics. */
|
|
54
|
+
version?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Optional lazy runtime bootstrap executed once per app/isolate, on the
|
|
57
|
+
* first request where bindings are available.
|
|
58
|
+
*/
|
|
59
|
+
bootstrap?: BootstrapHandler;
|
|
60
|
+
/** Modules contributed by the plugin. */
|
|
61
|
+
modules?: Module[];
|
|
62
|
+
/** Extensions contributed by the plugin. */
|
|
63
|
+
extensions?: Extension[];
|
|
64
|
+
/** Event subscribers wired to the caller's {@link EventBus} at registration. */
|
|
65
|
+
subscribers?: Subscriber[];
|
|
66
|
+
/** Link definitions contributed by the plugin. */
|
|
67
|
+
links?: LinkDefinition[];
|
|
68
|
+
/**
|
|
69
|
+
* Workflows contributed by the plugin. Collected and merged with
|
|
70
|
+
* module-owned workflows at `createApp()` boot. See
|
|
71
|
+
* {@link WorkflowDescriptor} for the structural contract.
|
|
72
|
+
*/
|
|
73
|
+
workflows?: readonly WorkflowDescriptor[];
|
|
74
|
+
/**
|
|
75
|
+
* Event filters contributed by the plugin. See
|
|
76
|
+
* {@link EventFilterDescriptor} for the structural contract.
|
|
77
|
+
*/
|
|
78
|
+
eventFilters?: readonly EventFilterDescriptor[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Identity helper that returns the plugin as-is. Exists purely so authors
|
|
82
|
+
* can write `definePlugin({ ... })` and get inference + IDE help without
|
|
83
|
+
* casting.
|
|
84
|
+
*/
|
|
85
|
+
export declare function definePlugin<P extends Plugin>(plugin: P): P;
|
|
86
|
+
/**
|
|
87
|
+
* Result of flattening a set of plugins.
|
|
88
|
+
*/
|
|
89
|
+
export interface RegisteredPlugins {
|
|
90
|
+
/** All modules contributed by the supplied plugins, in registration order. */
|
|
91
|
+
modules: Module[];
|
|
92
|
+
/** All extensions contributed by the supplied plugins. */
|
|
93
|
+
extensions: Extension[];
|
|
94
|
+
/** All link definitions contributed by the supplied plugins. */
|
|
95
|
+
links: LinkDefinition[];
|
|
96
|
+
/** All subscribers contributed, in registration order. */
|
|
97
|
+
subscribers: Subscriber[];
|
|
98
|
+
/** Subscription handles for subscribers attached to the event bus. */
|
|
99
|
+
subscriptions: Array<{
|
|
100
|
+
unsubscribe(): void;
|
|
101
|
+
}>;
|
|
102
|
+
/** All workflows contributed by the supplied plugins, in registration order. */
|
|
103
|
+
workflows: WorkflowDescriptor[];
|
|
104
|
+
/** All event filters contributed by the supplied plugins, in registration order. */
|
|
105
|
+
eventFilters: EventFilterDescriptor[];
|
|
106
|
+
}
|
|
107
|
+
export interface RegisterPluginsOptions {
|
|
108
|
+
/** Event bus to attach subscribers to. If omitted, subscribers are collected but not wired. */
|
|
109
|
+
eventBus?: EventBus;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Flatten a list of plugins into their constituent pieces and optionally
|
|
113
|
+
* attach event subscribers to an {@link EventBus}.
|
|
114
|
+
*
|
|
115
|
+
* Throws if two plugins declare the same `name`.
|
|
116
|
+
*/
|
|
117
|
+
export declare function registerPlugins(plugins: ReadonlyArray<Plugin>, options?: RegisterPluginsOptions): RegisteredPlugins;
|
|
118
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,SAAS,EACT,MAAM,EACN,kBAAkB,EACnB,MAAM,aAAa,CAAA;AAEpB;;;;;GAKG;AACH,MAAM,WAAW,UAAU,CACzB,KAAK,GAAG,OAAO,EACf,SAAS,SAAS,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS;IAEvE,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,OAAO,EAAE,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IACvC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,MAAM;IACrB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAA;IAC5B,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,SAAS,EAAE,CAAA;IACxB,gFAAgF;IAChF,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;IAC1B,kDAAkD;IAClD,KAAK,CAAC,EAAE,cAAc,EAAE,CAAA;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACzC;;;OAGG;IACH,YAAY,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAA;CAChD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAE3D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,0DAA0D;IAC1D,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,gEAAgE;IAChE,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,0DAA0D;IAC1D,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,sEAAsE;IACtE,aAAa,EAAE,KAAK,CAAC;QAAE,WAAW,IAAI,IAAI,CAAA;KAAE,CAAC,CAAA;IAC7C,gFAAgF;IAChF,SAAS,EAAE,kBAAkB,EAAE,CAAA;IAC/B,oFAAoF;IACpF,YAAY,EAAE,qBAAqB,EAAE,CAAA;CACtC;AAED,MAAM,WAAW,sBAAsB;IACrC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,OAAO,GAAE,sBAA2B,GACnC,iBAAiB,CAkCnB"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugins — optional distributable bundles that group modules, extensions,
|
|
3
|
+
* event subscribers, and link definitions into a single unit.
|
|
4
|
+
*
|
|
5
|
+
* A plugin is the unit of "distribution" in Voyant: a customer, vendor, or
|
|
6
|
+
* integrator ships a plugin package and it can be registered alongside core
|
|
7
|
+
* modules without touching the framework itself. It is not the default runtime
|
|
8
|
+
* customization unit — modules, providers, extensions, and workflows should be
|
|
9
|
+
* preferred when a smaller seam fits.
|
|
10
|
+
*
|
|
11
|
+
* Core plugins are transport-agnostic — they contain {@link Module} and
|
|
12
|
+
* {@link Extension} values (no HTTP routes). Transport adapters (such as
|
|
13
|
+
* `@voyant-travel/hono`) layer their own plugin shape on top of this
|
|
14
|
+
* contract to carry route bundles.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Identity helper that returns the plugin as-is. Exists purely so authors
|
|
18
|
+
* can write `definePlugin({ ... })` and get inference + IDE help without
|
|
19
|
+
* casting.
|
|
20
|
+
*/
|
|
21
|
+
export function definePlugin(plugin) {
|
|
22
|
+
return plugin;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Flatten a list of plugins into their constituent pieces and optionally
|
|
26
|
+
* attach event subscribers to an {@link EventBus}.
|
|
27
|
+
*
|
|
28
|
+
* Throws if two plugins declare the same `name`.
|
|
29
|
+
*/
|
|
30
|
+
export function registerPlugins(plugins, options = {}) {
|
|
31
|
+
const seen = new Set();
|
|
32
|
+
const modules = [];
|
|
33
|
+
const extensions = [];
|
|
34
|
+
const links = [];
|
|
35
|
+
const subscribers = [];
|
|
36
|
+
const subscriptions = [];
|
|
37
|
+
const workflows = [];
|
|
38
|
+
const eventFilters = [];
|
|
39
|
+
for (const plugin of plugins) {
|
|
40
|
+
if (seen.has(plugin.name)) {
|
|
41
|
+
throw new Error(`Duplicate plugin name: "${plugin.name}"`);
|
|
42
|
+
}
|
|
43
|
+
seen.add(plugin.name);
|
|
44
|
+
if (plugin.modules)
|
|
45
|
+
modules.push(...plugin.modules);
|
|
46
|
+
if (plugin.extensions)
|
|
47
|
+
extensions.push(...plugin.extensions);
|
|
48
|
+
if (plugin.links)
|
|
49
|
+
links.push(...plugin.links);
|
|
50
|
+
if (plugin.subscribers) {
|
|
51
|
+
for (const sub of plugin.subscribers) {
|
|
52
|
+
subscribers.push(sub);
|
|
53
|
+
if (options.eventBus) {
|
|
54
|
+
subscriptions.push(options.eventBus.subscribe(sub.event, sub.handler, { inline: sub.inline ?? false }));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (plugin.workflows)
|
|
59
|
+
workflows.push(...plugin.workflows);
|
|
60
|
+
if (plugin.eventFilters)
|
|
61
|
+
eventFilters.push(...plugin.eventFilters);
|
|
62
|
+
}
|
|
63
|
+
return { modules, extensions, links, subscribers, subscriptions, workflows, eventFilters };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA8EH;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAmB,MAAS;IACtD,OAAO,MAAM,CAAA;AACf,CAAC;AA2BD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,OAA8B,EAC9B,UAAkC,EAAE;IAEpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,MAAM,UAAU,GAAgB,EAAE,CAAA;IAClC,MAAM,KAAK,GAAqB,EAAE,CAAA;IAClC,MAAM,WAAW,GAAiB,EAAE,CAAA;IACpC,MAAM,aAAa,GAAmC,EAAE,CAAA;IACxD,MAAM,SAAS,GAAyB,EAAE,CAAA;IAC1C,MAAM,YAAY,GAA4B,EAAE,CAAA;IAEhD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,IAAI,GAAG,CAAC,CAAA;QAC5D,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAErB,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;QACnD,IAAI,MAAM,CAAC,UAAU;YAAE,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;QAC5D,IAAI,MAAM,CAAC,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QAC7C,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACrB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACrB,aAAa,CAAC,IAAI,CAChB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CACpF,CAAA;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,SAAS;YAAE,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;QACzD,IAAI,MAAM,CAAC,YAAY;YAAE,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;IACpE,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,CAAA;AAC5F,CAAC"}
|
package/dist/query.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Graph — cross-module reads that traverse {@link LinkDefinition}s.
|
|
3
|
+
*
|
|
4
|
+
* Modules expose {@link EntityFetcher}s for their entities. The graph
|
|
5
|
+
* planner fetches base records, walks link definitions for any dotted
|
|
6
|
+
* fields in the selection, issues parallel fetches for the linked
|
|
7
|
+
* entities, and stitches the results in-memory.
|
|
8
|
+
*
|
|
9
|
+
* This is an application-layer join, not a SQL join: modules never
|
|
10
|
+
* import one another's tables, and there are no database foreign keys
|
|
11
|
+
* between module schemas.
|
|
12
|
+
*/
|
|
13
|
+
import type { LinkDefinition, LinkService } from "./links.js";
|
|
14
|
+
/** Filters applied to the underlying entity fetcher. */
|
|
15
|
+
export type QueryFilters = Record<string, unknown>;
|
|
16
|
+
/** Per-request hints threaded through cross-module reads. */
|
|
17
|
+
export type QueryContextValue = Record<string, unknown>;
|
|
18
|
+
export interface QueryPagination {
|
|
19
|
+
skip?: number;
|
|
20
|
+
take?: number;
|
|
21
|
+
}
|
|
22
|
+
/** Arguments passed to an {@link EntityFetcher}'s `list` method. */
|
|
23
|
+
export interface EntityFetcherArgs {
|
|
24
|
+
filters?: QueryFilters;
|
|
25
|
+
ids?: string[];
|
|
26
|
+
pagination?: QueryPagination;
|
|
27
|
+
context?: QueryContextValue;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A minimal record shape. Concrete module records can extend this with
|
|
31
|
+
* additional fields; the query planner only requires `id` to join on.
|
|
32
|
+
*/
|
|
33
|
+
export type EntityRecord = Record<string, unknown> & {
|
|
34
|
+
id: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Per-entity data loader. Modules register one fetcher per entity they
|
|
38
|
+
* want to expose to cross-module reads.
|
|
39
|
+
*
|
|
40
|
+
* Implementations MUST honour both the `filters`/`pagination` path
|
|
41
|
+
* (top-level entity fetch) and the `ids` path (used to hydrate link
|
|
42
|
+
* targets). When both are provided, `ids` takes precedence.
|
|
43
|
+
*/
|
|
44
|
+
export interface EntityFetcher {
|
|
45
|
+
list(args: EntityFetcherArgs): Promise<EntityRecord[]>;
|
|
46
|
+
}
|
|
47
|
+
export interface QueryGraphConfig {
|
|
48
|
+
/** Name of the entity to fetch. Must match a registered fetcher's key. */
|
|
49
|
+
entity: string;
|
|
50
|
+
/**
|
|
51
|
+
* Flat list of field paths to select.
|
|
52
|
+
*
|
|
53
|
+
* - `"id"`, `"title"` — scalar fields (ignored by the planner; honoured by the fetcher).
|
|
54
|
+
* - `"products.*"` — traverses the `entity → products` link.
|
|
55
|
+
* - `"organization.name"` — traverses the `entity → organization` link; only `name` is hydrated.
|
|
56
|
+
*
|
|
57
|
+
* Nested paths (`"products.categories.*"`) are NOT supported in the MVP.
|
|
58
|
+
*/
|
|
59
|
+
fields: string[];
|
|
60
|
+
filters?: QueryFilters;
|
|
61
|
+
pagination?: QueryPagination;
|
|
62
|
+
/**
|
|
63
|
+
* Per-request runtime hints such as locale, market, actor, or pricing
|
|
64
|
+
* context. The query planner passes this through unchanged to every
|
|
65
|
+
* participating entity fetcher.
|
|
66
|
+
*/
|
|
67
|
+
context?: QueryContextValue;
|
|
68
|
+
}
|
|
69
|
+
export interface QueryGraphResult {
|
|
70
|
+
data: EntityRecord[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Callable query runtime exposed to routes and workflows.
|
|
74
|
+
*
|
|
75
|
+
* It wraps a fixed {@link QueryGraphContext} so callers only supply the
|
|
76
|
+
* per-request graph config.
|
|
77
|
+
*/
|
|
78
|
+
export type QueryRunner = (config: QueryGraphConfig) => Promise<QueryGraphResult>;
|
|
79
|
+
export interface QueryGraphContext {
|
|
80
|
+
/** Entity name → fetcher. */
|
|
81
|
+
fetchers: Map<string, EntityFetcher>;
|
|
82
|
+
/** Known cross-module link definitions. */
|
|
83
|
+
links: LinkDefinition[];
|
|
84
|
+
/** Runtime link service (pivot table reads). */
|
|
85
|
+
linkService: LinkService;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Build a {@link QueryGraphContext} from plain records.
|
|
89
|
+
*/
|
|
90
|
+
export declare function createQueryContext(fetchers: Record<string, EntityFetcher>, links: LinkDefinition[], linkService: LinkService): QueryGraphContext;
|
|
91
|
+
/**
|
|
92
|
+
* Wrap a fixed {@link QueryGraphContext} in a callable runtime.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createQueryRunner(ctx: QueryGraphContext): QueryRunner;
|
|
95
|
+
/**
|
|
96
|
+
* Execute a cross-module read.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* const { data } = await queryGraph(ctx, {
|
|
101
|
+
* entity: "person",
|
|
102
|
+
* fields: ["id", "name", "product.*", "organization.name"],
|
|
103
|
+
* filters: { country: "FR" },
|
|
104
|
+
* pagination: { take: 50 },
|
|
105
|
+
* })
|
|
106
|
+
* // data[0].product === [{ id: "prod_...", ... }, ...]
|
|
107
|
+
* // data[0].organization === { id: "org_...", name: "..." } | null
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function queryGraph(ctx: QueryGraphContext, config: QueryGraphConfig): Promise<QueryGraphResult>;
|
|
111
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7D,wDAAwD;AACxD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAClD,6DAA6D;AAC7D,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;IACd,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,OAAO,CAAC,EAAE,iBAAiB,CAAA;CAC5B;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnE;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;CACvD;AAED,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;;;OAQG;IACH,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,EAAE,CAAA;CACrB;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAEjF,MAAM,WAAW,iBAAiB;IAChC,6BAA6B;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACpC,2CAA2C;IAC3C,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,gDAAgD;IAChD,WAAW,EAAE,WAAW,CAAA;CACzB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EACvC,KAAK,EAAE,cAAc,EAAE,EACvB,WAAW,EAAE,WAAW,GACvB,iBAAiB,CAEnB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,GAAG,WAAW,CAErE;AA2CD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAkE3B"}
|