@ontrails/core 1.0.0-beta.11 → 1.0.0-beta.13
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/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +67 -30
- package/README.md +19 -19
- package/dist/context.d.ts +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +5 -4
- package/dist/context.js.map +1 -1
- package/dist/derive.d.ts +8 -3
- package/dist/derive.d.ts.map +1 -1
- package/dist/derive.js +7 -7
- package/dist/derive.js.map +1 -1
- package/dist/event.d.ts +4 -41
- package/dist/event.d.ts.map +1 -1
- package/dist/event.js +4 -14
- package/dist/event.js.map +1 -1
- package/dist/execute.d.ts +11 -9
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +34 -151
- package/dist/execute.js.map +1 -1
- package/dist/gate.d.ts +17 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +21 -0
- package/dist/gate.js.map +1 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -7
- package/dist/index.js.map +1 -1
- package/dist/layer.d.ts +5 -16
- package/dist/layer.d.ts.map +1 -1
- package/dist/layer.js +3 -20
- package/dist/layer.js.map +1 -1
- package/dist/provision-config.d.ts +22 -0
- package/dist/provision-config.d.ts.map +1 -0
- package/dist/provision-config.js +210 -0
- package/dist/provision-config.js.map +1 -0
- package/dist/provision.d.ts +71 -0
- package/dist/provision.d.ts.map +1 -0
- package/dist/provision.js +56 -0
- package/dist/provision.js.map +1 -0
- package/dist/run.d.ts +27 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +34 -0
- package/dist/run.js.map +1 -0
- package/dist/service-config.d.ts +22 -0
- package/dist/service-config.d.ts.map +1 -0
- package/dist/service-config.js +210 -0
- package/dist/service-config.js.map +1 -0
- package/dist/service.d.ts +39 -37
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +21 -21
- package/dist/service.js.map +1 -1
- package/dist/signal.d.ts +33 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +17 -0
- package/dist/signal.js.map +1 -0
- package/dist/topo.d.ts +10 -10
- package/dist/topo.d.ts.map +1 -1
- package/dist/topo.js +48 -35
- package/dist/topo.js.map +1 -1
- package/dist/trail.d.ts +19 -17
- package/dist/trail.d.ts.map +1 -1
- package/dist/trail.js +5 -4
- package/dist/trail.js.map +1 -1
- package/dist/types.d.ts +26 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -1
- package/dist/validate-topo.d.ts +2 -2
- package/dist/validate-topo.js +31 -31
- package/dist/validate-topo.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/context.test.ts +8 -8
- package/src/__tests__/execute.test.ts +124 -122
- package/src/__tests__/{layer.test.ts → gate.test.ts} +26 -26
- package/src/__tests__/{dispatch.test.ts → run.test.ts} +39 -39
- package/src/__tests__/service-config.test.ts +228 -0
- package/src/__tests__/service.test.ts +71 -71
- package/src/__tests__/{event.test.ts → signal.test.ts} +15 -15
- package/src/__tests__/topo.test.ts +54 -54
- package/src/__tests__/trail-permit.test.ts +60 -0
- package/src/__tests__/trail.test.ts +58 -58
- package/src/__tests__/type-utils.test.ts +3 -3
- package/src/__tests__/validate-topo.test.ts +38 -38
- package/src/context.ts +5 -4
- package/src/derive.ts +8 -8
- package/src/event.ts +11 -73
- package/src/execute.ts +59 -238
- package/src/{layer.ts → gate.ts} +13 -13
- package/src/index.ts +26 -21
- package/src/provision-config.ts +373 -0
- package/src/provision.ts +148 -0
- package/src/{dispatch.ts → run.ts} +8 -8
- package/src/signal.ts +65 -0
- package/src/topo.ts +74 -52
- package/src/trail.ts +30 -23
- package/src/types.ts +30 -10
- package/src/validate-topo.ts +33 -33
- package/tsconfig.tsbuildinfo +1 -1
- package/src/service.ts +0 -139
|
@@ -8,14 +8,14 @@ import type { TrailInput, TrailOutput, TrailResult } from '../type-utils';
|
|
|
8
8
|
import { inputOf, outputOf } from '../type-utils';
|
|
9
9
|
|
|
10
10
|
const greetTrail = trail('greet', {
|
|
11
|
+
blaze: (input) => Result.ok({ message: `Hello, ${input.name}!` }),
|
|
11
12
|
input: z.object({ name: z.string() }),
|
|
12
13
|
output: z.object({ message: z.string() }),
|
|
13
|
-
run: (input) => Result.ok({ message: `Hello, ${input.name}!` }),
|
|
14
14
|
});
|
|
15
15
|
|
|
16
16
|
const noOutputTrail = trail('ping', {
|
|
17
|
+
blaze: () => Result.ok(),
|
|
17
18
|
input: z.object({}),
|
|
18
|
-
run: () => Result.ok(),
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
describe('type-utils', () => {
|
|
@@ -71,9 +71,9 @@ describe('type-utils', () => {
|
|
|
71
71
|
describe('TrailResult', () => {
|
|
72
72
|
test('extracts Result<Output, Error> from a trail', () => {
|
|
73
73
|
const t = trail('test.result', {
|
|
74
|
+
blaze: (input) => Result.ok({ answer: input.q }),
|
|
74
75
|
input: z.object({ q: z.string() }),
|
|
75
76
|
output: z.object({ answer: z.string() }),
|
|
76
|
-
run: (input) => Result.ok({ answer: input.q }),
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
type Expected = Result<{ answer: string }, Error>;
|
|
@@ -2,8 +2,8 @@ import { describe, expect, test } from 'bun:test';
|
|
|
2
2
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
|
+
import { provision } from '../provision.js';
|
|
5
6
|
import { Result } from '../result.js';
|
|
6
|
-
import { service } from '../service.js';
|
|
7
7
|
import { topo } from '../topo.js';
|
|
8
8
|
import type { TopoIssue } from '../validate-topo.js';
|
|
9
9
|
import { validateTopo } from '../validate-topo.js';
|
|
@@ -18,7 +18,7 @@ const noop = async () => Result.ok();
|
|
|
18
18
|
const mockTrail = (
|
|
19
19
|
id: string,
|
|
20
20
|
overrides?: {
|
|
21
|
-
|
|
21
|
+
crosses?: readonly string[];
|
|
22
22
|
examples?: readonly {
|
|
23
23
|
name: string;
|
|
24
24
|
input: unknown;
|
|
@@ -26,27 +26,27 @@ const mockTrail = (
|
|
|
26
26
|
error?: string;
|
|
27
27
|
}[];
|
|
28
28
|
output?: z.ZodType;
|
|
29
|
-
|
|
29
|
+
provisions?: readonly ReturnType<typeof provision>[];
|
|
30
30
|
}
|
|
31
31
|
) => ({
|
|
32
|
-
|
|
32
|
+
blaze: noop,
|
|
33
|
+
crosses: Object.freeze([...(overrides?.crosses ?? [])]),
|
|
33
34
|
id,
|
|
34
35
|
input: z.object({ name: z.string() }),
|
|
35
36
|
kind: 'trail' as const,
|
|
36
|
-
|
|
37
|
-
services: Object.freeze([...(overrides?.services ?? [])]),
|
|
37
|
+
provisions: Object.freeze([...(overrides?.provisions ?? [])]),
|
|
38
38
|
...overrides,
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
const
|
|
42
|
-
|
|
41
|
+
const mockProvision = (id: string) =>
|
|
42
|
+
provision(id, {
|
|
43
43
|
create: () => Result.ok({ id }),
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
const mockEvent = (id: string, from?: readonly string[]) => ({
|
|
47
47
|
from,
|
|
48
48
|
id,
|
|
49
|
-
kind: '
|
|
49
|
+
kind: 'signal' as const,
|
|
50
50
|
payload: z.object({ data: z.string() }),
|
|
51
51
|
});
|
|
52
52
|
|
|
@@ -68,7 +68,7 @@ describe('validateTopo', () => {
|
|
|
68
68
|
const app = topo('app', {
|
|
69
69
|
add: mockTrail('entity.add'),
|
|
70
70
|
onboard: mockTrail('entity.onboard', {
|
|
71
|
-
|
|
71
|
+
crosses: ['entity.add'],
|
|
72
72
|
}),
|
|
73
73
|
updated: mockEvent('entity.updated', ['entity.add']),
|
|
74
74
|
});
|
|
@@ -77,11 +77,11 @@ describe('validateTopo', () => {
|
|
|
77
77
|
expect(result.isOk()).toBe(true);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
-
describe('trail
|
|
81
|
-
test('trail
|
|
80
|
+
describe('trail crossing', () => {
|
|
81
|
+
test('trail crossing a non-existent trail fails', () => {
|
|
82
82
|
const app = topo('app', {
|
|
83
83
|
onboard: mockTrail('entity.onboard', {
|
|
84
|
-
|
|
84
|
+
crosses: ['entity.missing'],
|
|
85
85
|
}),
|
|
86
86
|
});
|
|
87
87
|
|
|
@@ -90,57 +90,57 @@ describe('validateTopo', () => {
|
|
|
90
90
|
|
|
91
91
|
const issues = extractIssues(result);
|
|
92
92
|
expect(issues).toHaveLength(1);
|
|
93
|
-
expect(issues[0]?.rule).toBe('
|
|
93
|
+
expect(issues[0]?.rule).toBe('cross-exists');
|
|
94
94
|
expect(issues[0]?.message).toContain('entity.missing');
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
test('trail
|
|
97
|
+
test('trail crossing itself fails', () => {
|
|
98
98
|
const app = topo('app', {
|
|
99
|
-
loop: mockTrail('entity.loop', {
|
|
99
|
+
loop: mockTrail('entity.loop', { crosses: ['entity.loop'] }),
|
|
100
100
|
});
|
|
101
101
|
|
|
102
102
|
const result = validateTopo(app);
|
|
103
103
|
expect(result.isErr()).toBe(true);
|
|
104
104
|
|
|
105
105
|
const issues = extractIssues(result);
|
|
106
|
-
expect(issues.some((i) => i.rule === 'no-self-
|
|
106
|
+
expect(issues.some((i) => i.rule === 'no-self-cross')).toBe(true);
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
test('two-node cycle (a→b→a) is detected', () => {
|
|
110
110
|
const app = topo('app', {
|
|
111
|
-
a: mockTrail('a', {
|
|
112
|
-
b: mockTrail('b', {
|
|
111
|
+
a: mockTrail('a', { crosses: ['b'] }),
|
|
112
|
+
b: mockTrail('b', { crosses: ['a'] }),
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
const result = validateTopo(app);
|
|
116
116
|
expect(result.isErr()).toBe(true);
|
|
117
117
|
|
|
118
118
|
const issues = extractIssues(result);
|
|
119
|
-
const cycleIssues = issues.filter((i) => i.rule === '
|
|
119
|
+
const cycleIssues = issues.filter((i) => i.rule === 'cross-cycle');
|
|
120
120
|
expect(cycleIssues.length).toBeGreaterThanOrEqual(1);
|
|
121
121
|
expect(cycleIssues[0]?.message).toContain('Cycle detected');
|
|
122
122
|
});
|
|
123
123
|
|
|
124
124
|
test('three-node cycle (a→b→c→a) is detected', () => {
|
|
125
125
|
const app = topo('app', {
|
|
126
|
-
a: mockTrail('a', {
|
|
127
|
-
b: mockTrail('b', {
|
|
128
|
-
c: mockTrail('c', {
|
|
126
|
+
a: mockTrail('a', { crosses: ['b'] }),
|
|
127
|
+
b: mockTrail('b', { crosses: ['c'] }),
|
|
128
|
+
c: mockTrail('c', { crosses: ['a'] }),
|
|
129
129
|
});
|
|
130
130
|
|
|
131
131
|
const result = validateTopo(app);
|
|
132
132
|
expect(result.isErr()).toBe(true);
|
|
133
133
|
|
|
134
134
|
const issues = extractIssues(result);
|
|
135
|
-
const cycleIssues = issues.filter((i) => i.rule === '
|
|
135
|
+
const cycleIssues = issues.filter((i) => i.rule === 'cross-cycle');
|
|
136
136
|
expect(cycleIssues.length).toBeGreaterThanOrEqual(1);
|
|
137
137
|
expect(cycleIssues[0]?.message).toContain('Cycle detected');
|
|
138
138
|
});
|
|
139
139
|
|
|
140
140
|
test('valid DAG with shared targets is not flagged', () => {
|
|
141
141
|
const app = topo('app', {
|
|
142
|
-
a: mockTrail('a', {
|
|
143
|
-
b: mockTrail('b', {
|
|
142
|
+
a: mockTrail('a', { crosses: ['c'] }),
|
|
143
|
+
b: mockTrail('b', { crosses: ['c'] }),
|
|
144
144
|
c: mockTrail('c'),
|
|
145
145
|
});
|
|
146
146
|
|
|
@@ -149,13 +149,13 @@ describe('validateTopo', () => {
|
|
|
149
149
|
});
|
|
150
150
|
});
|
|
151
151
|
|
|
152
|
-
describe('
|
|
153
|
-
test('trail declaring a registered
|
|
154
|
-
const db =
|
|
152
|
+
describe('provision declarations', () => {
|
|
153
|
+
test('trail declaring a registered provision passes', () => {
|
|
154
|
+
const db = mockProvision('db.main');
|
|
155
155
|
const app = topo('app', {
|
|
156
156
|
db,
|
|
157
157
|
show: mockTrail('entity.show', {
|
|
158
|
-
|
|
158
|
+
provisions: [db],
|
|
159
159
|
}),
|
|
160
160
|
});
|
|
161
161
|
|
|
@@ -163,11 +163,11 @@ describe('validateTopo', () => {
|
|
|
163
163
|
expect(result.isOk()).toBe(true);
|
|
164
164
|
});
|
|
165
165
|
|
|
166
|
-
test('trail declaring a missing
|
|
167
|
-
const db =
|
|
166
|
+
test('trail declaring a missing provision fails', () => {
|
|
167
|
+
const db = mockProvision('db.main');
|
|
168
168
|
const app = topo('app', {
|
|
169
169
|
show: mockTrail('entity.show', {
|
|
170
|
-
|
|
170
|
+
provisions: [db],
|
|
171
171
|
}),
|
|
172
172
|
});
|
|
173
173
|
|
|
@@ -176,7 +176,7 @@ describe('validateTopo', () => {
|
|
|
176
176
|
|
|
177
177
|
const issues = extractIssues(result);
|
|
178
178
|
expect(issues).toHaveLength(1);
|
|
179
|
-
expect(issues[0]?.rule).toBe('
|
|
179
|
+
expect(issues[0]?.rule).toBe('provision-exists');
|
|
180
180
|
expect(issues[0]?.message).toContain('db.main');
|
|
181
181
|
});
|
|
182
182
|
});
|
|
@@ -286,7 +286,7 @@ describe('validateTopo', () => {
|
|
|
286
286
|
|
|
287
287
|
const issues = extractIssues(result);
|
|
288
288
|
expect(issues).toHaveLength(1);
|
|
289
|
-
expect(issues[0]?.rule).toBe('
|
|
289
|
+
expect(issues[0]?.rule).toBe('signal-origin-exists');
|
|
290
290
|
expect(issues[0]?.message).toContain('entity.ghost');
|
|
291
291
|
});
|
|
292
292
|
|
|
@@ -301,11 +301,11 @@ describe('validateTopo', () => {
|
|
|
301
301
|
});
|
|
302
302
|
|
|
303
303
|
test('collects multiple issues', () => {
|
|
304
|
-
const db =
|
|
304
|
+
const db = mockProvision('db.main');
|
|
305
305
|
const app = topo('app', {
|
|
306
|
-
broken: mockTrail('entity.broken', {
|
|
306
|
+
broken: mockTrail('entity.broken', { crosses: ['entity.missing'] }),
|
|
307
307
|
missingService: mockTrail('entity.missing-service', {
|
|
308
|
-
|
|
308
|
+
provisions: [db],
|
|
309
309
|
}),
|
|
310
310
|
show: mockTrail('entity.show', {
|
|
311
311
|
examples: [{ input: { name: 123 }, name: 'Bad' }],
|
package/src/context.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createProvisionLookup } from './provision.js';
|
|
2
2
|
import type { TrailContext, TrailContextInit } from './types.js';
|
|
3
3
|
|
|
4
4
|
type MutableTrailContext = {
|
|
@@ -9,19 +9,20 @@ type MutableTrailContext = {
|
|
|
9
9
|
* Create a TrailContext with sensible defaults.
|
|
10
10
|
*
|
|
11
11
|
* - `requestId` defaults to `Bun.randomUUIDv7()` (sortable v7 UUID)
|
|
12
|
-
* - `
|
|
12
|
+
* - `abortSignal` defaults to a fresh, non-aborted `AbortSignal`
|
|
13
13
|
* - All other fields come from `overrides`
|
|
14
14
|
*/
|
|
15
15
|
export const createTrailContext = (
|
|
16
16
|
overrides?: Partial<TrailContextInit>
|
|
17
17
|
): TrailContext => {
|
|
18
18
|
const ctx = {
|
|
19
|
+
abortSignal: new AbortController().signal,
|
|
19
20
|
cwd: process.cwd(),
|
|
20
21
|
env: process.env as Record<string, string | undefined>,
|
|
21
22
|
requestId: Bun.randomUUIDv7(),
|
|
22
|
-
signal: new AbortController().signal,
|
|
23
23
|
...overrides,
|
|
24
24
|
} as MutableTrailContext;
|
|
25
|
-
|
|
25
|
+
const lookup = overrides?.provision ?? createProvisionLookup(() => ctx);
|
|
26
|
+
ctx.provision = lookup;
|
|
26
27
|
return ctx;
|
|
27
28
|
};
|
package/src/derive.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Schema-driven field derivation for @ontrails/core
|
|
3
3
|
*
|
|
4
|
-
* Introspects Zod v4 schemas to produce a
|
|
5
|
-
* that UI
|
|
4
|
+
* Introspects Zod v4 schemas to produce a runtime-agnostic Field[] descriptor
|
|
5
|
+
* that UI consumers (CLI prompts, web forms, etc.) can consume.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { z } from 'zod';
|
|
@@ -11,7 +11,7 @@ import type { z } from 'zod';
|
|
|
11
11
|
// Public types
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
13
|
|
|
14
|
-
/** A
|
|
14
|
+
/** A runtime-agnostic field descriptor derived from a Zod schema. */
|
|
15
15
|
export interface Field {
|
|
16
16
|
readonly name: string;
|
|
17
17
|
readonly type:
|
|
@@ -193,11 +193,6 @@ const buildOptions = (
|
|
|
193
193
|
// Public API
|
|
194
194
|
// ---------------------------------------------------------------------------
|
|
195
195
|
|
|
196
|
-
/**
|
|
197
|
-
* Derive a surface-agnostic Field[] from a Zod object schema.
|
|
198
|
-
*
|
|
199
|
-
* Uses Zod v4's `_zod.def` for introspection. Returns fields sorted by name.
|
|
200
|
-
*/
|
|
201
196
|
/** Derive a single field from a shape entry. */
|
|
202
197
|
const deriveField = (
|
|
203
198
|
key: string,
|
|
@@ -212,6 +207,11 @@ const deriveField = (
|
|
|
212
207
|
return { default: defaultValue, label, name: key, options, required, type };
|
|
213
208
|
};
|
|
214
209
|
|
|
210
|
+
/**
|
|
211
|
+
* Derive a runtime-agnostic Field[] from a Zod object schema.
|
|
212
|
+
*
|
|
213
|
+
* Uses Zod v4's `_zod.def` for introspection. Returns fields sorted by name.
|
|
214
|
+
*/
|
|
215
215
|
export const deriveFields = (
|
|
216
216
|
schema: z.ZodType,
|
|
217
217
|
overrides?: Record<string, FieldOverride>
|
package/src/event.ts
CHANGED
|
@@ -1,77 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { z } from 'zod';
|
|
6
|
-
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
// Spec (input to the factory)
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
|
|
11
|
-
export interface EventSpec<T> {
|
|
12
|
-
readonly payload: z.ZodType<T>;
|
|
13
|
-
readonly description?: string | undefined;
|
|
14
|
-
readonly metadata?: Readonly<Record<string, unknown>> | undefined;
|
|
15
|
-
/** Trail IDs that produce this event (e.g. the trails it originates from). */
|
|
16
|
-
readonly from?: readonly string[] | undefined;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// ---------------------------------------------------------------------------
|
|
20
|
-
// Shape (output of the factory)
|
|
21
|
-
// ---------------------------------------------------------------------------
|
|
22
|
-
|
|
23
|
-
export interface Event<T> {
|
|
24
|
-
readonly id: string;
|
|
25
|
-
readonly kind: 'event';
|
|
26
|
-
readonly payload: z.ZodType<T>;
|
|
27
|
-
readonly description?: string | undefined;
|
|
28
|
-
readonly metadata?: Readonly<Record<string, unknown>> | undefined;
|
|
29
|
-
/** Trail IDs that produce this event (e.g. the trails it originates from). */
|
|
30
|
-
readonly from?: readonly string[] | undefined;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// ---------------------------------------------------------------------------
|
|
34
|
-
// Factory
|
|
35
|
-
// ---------------------------------------------------------------------------
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Create an event definition.
|
|
39
|
-
*
|
|
40
|
-
* An event is a named payload schema describing something that happened.
|
|
41
|
-
* Returns a frozen object with `kind: "event"` and all spec fields.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```typescript
|
|
45
|
-
* // ID as first argument
|
|
46
|
-
* const updated = event("entity.updated", {
|
|
47
|
-
* payload: EntityUpdatedSchema,
|
|
48
|
-
* from: ["entity.add", "entity.update"],
|
|
49
|
-
* });
|
|
2
|
+
* Legacy event aliases for the signal model.
|
|
50
3
|
*
|
|
51
|
-
*
|
|
52
|
-
* const updated = event({ id: "entity.updated", payload: ..., from: [...] });
|
|
53
|
-
* ```
|
|
4
|
+
* Keep this file as a compatibility seam while the repo-wide cutover lands.
|
|
54
5
|
*/
|
|
55
|
-
export function event<T>(id: string, spec: EventSpec<T>): Event<T>;
|
|
56
|
-
export function event<T>(
|
|
57
|
-
spec: EventSpec<T> & { readonly id: string }
|
|
58
|
-
): Event<T>;
|
|
59
|
-
export function event<T>(
|
|
60
|
-
idOrSpec: string | (EventSpec<T> & { readonly id: string }),
|
|
61
|
-
maybeSpec?: EventSpec<T>
|
|
62
|
-
): Event<T> {
|
|
63
|
-
const resolvedId = typeof idOrSpec === 'string' ? idOrSpec : idOrSpec.id;
|
|
64
|
-
// oxlint-disable-next-line no-non-null-assertion -- overload guarantees maybeSpec when idOrSpec is string
|
|
65
|
-
const resolvedSpec = typeof idOrSpec === 'string' ? maybeSpec! : idOrSpec;
|
|
66
|
-
return Object.freeze({
|
|
67
|
-
description: resolvedSpec.description,
|
|
68
|
-
from: resolvedSpec.from ? Object.freeze([...resolvedSpec.from]) : undefined,
|
|
69
|
-
id: resolvedId,
|
|
70
|
-
kind: 'event' as const,
|
|
71
|
-
metadata: resolvedSpec.metadata,
|
|
72
|
-
payload: resolvedSpec.payload,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
6
|
|
|
76
|
-
|
|
77
|
-
export type
|
|
7
|
+
export { signal as event } from './signal.js';
|
|
8
|
+
export type {
|
|
9
|
+
AnySignal,
|
|
10
|
+
AnySignal as AnyEvent,
|
|
11
|
+
Signal,
|
|
12
|
+
Signal as Event,
|
|
13
|
+
SignalSpec,
|
|
14
|
+
SignalSpec as EventSpec,
|
|
15
|
+
} from './signal.js';
|