@dxos/functions 0.5.3-main.7cd4303 → 0.5.3-main.7e64682
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/lib/browser/chunk-CMMH5BA6.mjs +86 -0
- package/dist/lib/browser/chunk-CMMH5BA6.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +390 -336
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types.mjs +14 -0
- package/dist/lib/browser/types.mjs.map +7 -0
- package/dist/lib/node/chunk-3C2FP4J4.cjs +103 -0
- package/dist/lib/node/chunk-3C2FP4J4.cjs.map +7 -0
- package/dist/lib/node/index.cjs +393 -333
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types.cjs +35 -0
- package/dist/lib/node/types.cjs.map +7 -0
- package/dist/types/src/browser/index.d.ts +2 -0
- package/dist/types/src/browser/index.d.ts.map +1 -0
- package/dist/types/src/{registry → function}/function-registry.d.ts +4 -4
- package/dist/types/src/function/function-registry.d.ts.map +1 -0
- package/dist/types/src/function/function-registry.test.d.ts.map +1 -0
- package/dist/types/src/function/index.d.ts.map +1 -0
- package/dist/types/src/handler.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.d.ts +1 -1
- package/dist/types/src/runtime/dev-server.d.ts.map +1 -1
- package/dist/types/src/runtime/scheduler.d.ts +2 -1
- package/dist/types/src/runtime/scheduler.d.ts.map +1 -1
- package/dist/types/src/testing/setup.d.ts.map +1 -1
- package/dist/types/src/trigger/trigger-registry.d.ts +2 -5
- package/dist/types/src/trigger/trigger-registry.d.ts.map +1 -1
- package/dist/types/src/trigger/type/subscription-trigger.d.ts.map +1 -1
- package/dist/types/src/trigger/type/timer-trigger.d.ts.map +1 -1
- package/dist/types/src/trigger/type/webhook-trigger.d.ts.map +1 -1
- package/dist/types/src/trigger/type/websocket-trigger.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +67 -43
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +31 -18
- package/schema/functions.json +23 -9
- package/src/browser/index.ts +5 -0
- package/src/{registry → function}/function-registry.test.ts +10 -10
- package/src/function/function-registry.ts +90 -0
- package/src/index.ts +1 -1
- package/src/runtime/dev-server.test.ts +2 -2
- package/src/runtime/dev-server.ts +8 -9
- package/src/runtime/scheduler.test.ts +15 -10
- package/src/runtime/scheduler.ts +26 -13
- package/src/testing/functions-integration.test.ts +2 -1
- package/src/testing/setup.ts +8 -10
- package/src/trigger/trigger-registry.test.ts +88 -45
- package/src/trigger/trigger-registry.ts +66 -31
- package/src/trigger/type/subscription-trigger.ts +30 -17
- package/src/trigger/type/timer-trigger.ts +4 -3
- package/src/trigger/type/webhook-trigger.ts +3 -2
- package/src/trigger/type/websocket-trigger.ts +4 -3
- package/src/types.ts +48 -37
- package/dist/types/src/registry/function-registry.d.ts.map +0 -1
- package/dist/types/src/registry/function-registry.test.d.ts.map +0 -1
- package/dist/types/src/registry/index.d.ts.map +0 -1
- package/src/registry/function-registry.ts +0 -84
- /package/dist/types/src/{registry → function}/function-registry.test.d.ts +0 -0
- /package/dist/types/src/{registry → function}/index.d.ts +0 -0
- /package/src/{registry → function}/index.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timer-trigger.d.ts","sourceRoot":"","sources":["../../../../../src/trigger/type/timer-trigger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"timer-trigger.d.ts","sourceRoot":"","sources":["../../../../../src/trigger/type/timer-trigger.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEhF,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,YAAY,CA8B3D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhook-trigger.d.ts","sourceRoot":"","sources":["../../../../../src/trigger/type/webhook-trigger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"webhook-trigger.d.ts","sourceRoot":"","sources":["../../../../../src/trigger/type/webhook-trigger.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEhF,eAAO,MAAM,oBAAoB,EAAE,cAAc,CAAC,cAAc,CAiC/D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-trigger.d.ts","sourceRoot":"","sources":["../../../../../src/trigger/type/websocket-trigger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"websocket-trigger.d.ts","sourceRoot":"","sources":["../../../../../src/trigger/type/websocket-trigger.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEhF,UAAU,uBAAuB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,cAAc,CAAC,gBAAgB,EAAE,uBAAuB,CAoE5F,CAAC"}
|
|
@@ -6,7 +6,7 @@ import { S } from '@dxos/echo-schema';
|
|
|
6
6
|
* https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions
|
|
7
7
|
*/
|
|
8
8
|
export type FunctionTriggerType = 'subscription' | 'timer' | 'webhook' | 'websocket';
|
|
9
|
-
declare const SubscriptionTriggerSchema: S.struct<{
|
|
9
|
+
declare const SubscriptionTriggerSchema: S.mutable<S.struct<{
|
|
10
10
|
type: S.literal<["subscription"]>;
|
|
11
11
|
filter: S.array<S.struct<{
|
|
12
12
|
type: S.$string;
|
|
@@ -23,12 +23,12 @@ declare const SubscriptionTriggerSchema: S.struct<{
|
|
|
23
23
|
readonly deep?: boolean | undefined;
|
|
24
24
|
readonly delay?: number | undefined;
|
|
25
25
|
} | undefined, never>;
|
|
26
|
-
}
|
|
26
|
+
}>>;
|
|
27
27
|
export type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;
|
|
28
|
-
declare const TimerTriggerSchema: S.struct<{
|
|
28
|
+
declare const TimerTriggerSchema: S.mutable<S.struct<{
|
|
29
29
|
type: S.literal<["timer"]>;
|
|
30
30
|
cron: S.$string;
|
|
31
|
-
}
|
|
31
|
+
}>>;
|
|
32
32
|
export type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;
|
|
33
33
|
declare const WebhookTriggerSchema: S.mutable<S.struct<{
|
|
34
34
|
type: S.literal<["webhook"]>;
|
|
@@ -36,7 +36,7 @@ declare const WebhookTriggerSchema: S.mutable<S.struct<{
|
|
|
36
36
|
port: S.PropertySignature<"?:", number | undefined, never, "?:", number | undefined, never>;
|
|
37
37
|
}>>;
|
|
38
38
|
export type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;
|
|
39
|
-
declare const WebsocketTriggerSchema: S.struct<{
|
|
39
|
+
declare const WebsocketTriggerSchema: S.mutable<S.struct<{
|
|
40
40
|
type: S.literal<["websocket"]>;
|
|
41
41
|
url: S.$string;
|
|
42
42
|
init: S.PropertySignature<"?:", {
|
|
@@ -44,7 +44,7 @@ declare const WebsocketTriggerSchema: S.struct<{
|
|
|
44
44
|
} | undefined, never, "?:", {
|
|
45
45
|
readonly [x: string]: any;
|
|
46
46
|
} | undefined, never>;
|
|
47
|
-
}
|
|
47
|
+
}>>;
|
|
48
48
|
export type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;
|
|
49
49
|
export type TriggerSpec = TimerTrigger | WebhookTrigger | WebsocketTrigger | SubscriptionTrigger;
|
|
50
50
|
declare const FunctionDef_base: import("@dxos/echo-schema").EchoSchemaClass<{
|
|
@@ -62,32 +62,33 @@ export declare class FunctionDef extends FunctionDef_base {
|
|
|
62
62
|
}
|
|
63
63
|
declare const FunctionTrigger_base: import("@dxos/echo-schema").EchoSchemaClass<{
|
|
64
64
|
function: string;
|
|
65
|
+
enabled?: boolean | undefined;
|
|
65
66
|
meta?: {
|
|
66
|
-
|
|
67
|
+
[x: string]: any;
|
|
67
68
|
} | undefined;
|
|
68
69
|
spec: {
|
|
69
|
-
|
|
70
|
+
filter: readonly {
|
|
70
71
|
readonly type: string;
|
|
71
72
|
readonly props?: {
|
|
72
73
|
readonly [x: string]: any;
|
|
73
74
|
} | undefined;
|
|
74
75
|
}[];
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
type: "subscription";
|
|
77
|
+
options?: {
|
|
77
78
|
readonly deep?: boolean | undefined;
|
|
78
79
|
readonly delay?: number | undefined;
|
|
79
80
|
} | undefined;
|
|
80
81
|
} | {
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
type: "timer";
|
|
83
|
+
cron: string;
|
|
83
84
|
} | {
|
|
84
85
|
port?: number | undefined;
|
|
85
86
|
type: "webhook";
|
|
86
87
|
method: string;
|
|
87
88
|
} | {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
type: "websocket";
|
|
90
|
+
url: string;
|
|
91
|
+
init?: {
|
|
91
92
|
readonly [x: string]: any;
|
|
92
93
|
} | undefined;
|
|
93
94
|
};
|
|
@@ -100,89 +101,112 @@ export declare class FunctionTrigger extends FunctionTrigger_base {
|
|
|
100
101
|
* Function manifest file.
|
|
101
102
|
*/
|
|
102
103
|
export declare const FunctionManifestSchema: S.struct<{
|
|
103
|
-
functions: S.PropertySignature<"?:",
|
|
104
|
+
functions: S.PropertySignature<"?:", ({
|
|
104
105
|
handler: string;
|
|
105
106
|
uri: string;
|
|
106
107
|
description?: string | undefined;
|
|
107
108
|
route: string;
|
|
108
109
|
} & {
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
"@meta"?: {
|
|
111
|
+
readonly keys: {
|
|
112
|
+
readonly id: string;
|
|
113
|
+
readonly source: string;
|
|
114
|
+
}[];
|
|
115
|
+
} | undefined;
|
|
116
|
+
})[] | undefined, never, "?:", ({
|
|
111
117
|
handler: string;
|
|
112
118
|
uri: string;
|
|
113
119
|
description?: string | undefined;
|
|
114
120
|
route: string;
|
|
115
121
|
} & {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
122
|
+
"@meta"?: {
|
|
123
|
+
readonly keys: {
|
|
124
|
+
readonly id: string;
|
|
125
|
+
readonly source: string;
|
|
126
|
+
}[];
|
|
127
|
+
} | undefined;
|
|
128
|
+
})[] | undefined, never>;
|
|
129
|
+
triggers: S.PropertySignature<"?:", ({
|
|
119
130
|
function: string;
|
|
131
|
+
enabled?: boolean | undefined;
|
|
120
132
|
meta?: {
|
|
121
|
-
|
|
133
|
+
[x: string]: any;
|
|
122
134
|
} | undefined;
|
|
123
135
|
spec: {
|
|
124
|
-
|
|
136
|
+
filter: readonly {
|
|
125
137
|
readonly type: string;
|
|
126
138
|
readonly props?: {
|
|
127
139
|
readonly [x: string]: any;
|
|
128
140
|
} | undefined;
|
|
129
141
|
}[];
|
|
130
|
-
|
|
131
|
-
|
|
142
|
+
type: "subscription";
|
|
143
|
+
options?: {
|
|
132
144
|
readonly deep?: boolean | undefined;
|
|
133
145
|
readonly delay?: number | undefined;
|
|
134
146
|
} | undefined;
|
|
135
147
|
} | {
|
|
136
|
-
|
|
137
|
-
|
|
148
|
+
type: "timer";
|
|
149
|
+
cron: string;
|
|
138
150
|
} | {
|
|
139
151
|
port?: number | undefined;
|
|
140
152
|
type: "webhook";
|
|
141
153
|
method: string;
|
|
142
154
|
} | {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
155
|
+
type: "websocket";
|
|
156
|
+
url: string;
|
|
157
|
+
init?: {
|
|
146
158
|
readonly [x: string]: any;
|
|
147
159
|
} | undefined;
|
|
148
160
|
};
|
|
149
161
|
} & {
|
|
150
|
-
|
|
151
|
-
|
|
162
|
+
"@meta"?: {
|
|
163
|
+
readonly keys: {
|
|
164
|
+
readonly id: string;
|
|
165
|
+
readonly source: string;
|
|
166
|
+
}[];
|
|
167
|
+
} | undefined;
|
|
168
|
+
})[] | undefined, never, "?:", ({
|
|
152
169
|
function: string;
|
|
170
|
+
enabled?: boolean | undefined;
|
|
153
171
|
meta?: {
|
|
154
|
-
|
|
172
|
+
[x: string]: any;
|
|
155
173
|
} | undefined;
|
|
156
174
|
spec: {
|
|
157
|
-
|
|
175
|
+
filter: readonly {
|
|
158
176
|
readonly type: string;
|
|
159
177
|
readonly props?: {
|
|
160
178
|
readonly [x: string]: any;
|
|
161
179
|
} | undefined;
|
|
162
180
|
}[];
|
|
163
|
-
|
|
164
|
-
|
|
181
|
+
type: "subscription";
|
|
182
|
+
options?: {
|
|
165
183
|
readonly deep?: boolean | undefined;
|
|
166
184
|
readonly delay?: number | undefined;
|
|
167
185
|
} | undefined;
|
|
168
186
|
} | {
|
|
169
|
-
|
|
170
|
-
|
|
187
|
+
type: "timer";
|
|
188
|
+
cron: string;
|
|
171
189
|
} | {
|
|
172
190
|
port?: number | undefined;
|
|
173
191
|
type: "webhook";
|
|
174
192
|
method: string;
|
|
175
193
|
} | {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
194
|
+
type: "websocket";
|
|
195
|
+
url: string;
|
|
196
|
+
init?: {
|
|
179
197
|
readonly [x: string]: any;
|
|
180
198
|
} | undefined;
|
|
181
199
|
};
|
|
182
200
|
} & {
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
"@meta"?: {
|
|
202
|
+
readonly keys: {
|
|
203
|
+
readonly id: string;
|
|
204
|
+
readonly source: string;
|
|
205
|
+
}[];
|
|
206
|
+
} | undefined;
|
|
207
|
+
})[] | undefined, never>;
|
|
185
208
|
}>;
|
|
186
209
|
export type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;
|
|
210
|
+
export declare const FUNCTION_SCHEMA: (typeof FunctionDef | typeof FunctionTrigger)[];
|
|
187
211
|
export {};
|
|
188
212
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAa,CAAC,EAAe,MAAM,mBAAmB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAErF,QAAA,MAAM,yBAAyB;;;;;;;;;;;;;;;;;GAmB9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAElF,QAAA,MAAM,kBAAkB;;;GAKvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,QAAA,MAAM,oBAAoB;;;;GAOzB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,QAAA,MAAM,sBAAsB;;;;;;;;GAM3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAS5E,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;;;;;;;;;AAEjG;;GAEG;AACH,qBAAa,WAAY,SAAQ,gBAQ/B;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEL,qBAAa,eAAgB,SAAQ,oBASnC;CAAG;AAEL;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAG5E,eAAO,MAAM,eAAe,iDAAiC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/functions",
|
|
3
|
-
"version": "0.5.3-main.
|
|
4
|
-
"description": "Functions
|
|
3
|
+
"version": "0.5.3-main.7e64682",
|
|
4
|
+
"description": "Functions API and runtime.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
7
|
"license": "MIT",
|
|
@@ -10,10 +10,24 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"browser": "./dist/lib/browser/index.mjs",
|
|
12
12
|
"node": "./dist/lib/node/index.cjs",
|
|
13
|
-
"default": "./dist/lib/node/index.cjs"
|
|
13
|
+
"default": "./dist/lib/node/index.cjs",
|
|
14
|
+
"types": "./dist/types/src/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./types": {
|
|
17
|
+
"browser": "./dist/lib/browser/types.mjs",
|
|
18
|
+
"node": "./dist/lib/node/types.cjs",
|
|
19
|
+
"default": "./dist/lib/node/types.cjs",
|
|
20
|
+
"types": "./dist/types/src/types.d.ts"
|
|
14
21
|
}
|
|
15
22
|
},
|
|
16
23
|
"types": "dist/types/src/index.d.ts",
|
|
24
|
+
"typesVersions": {
|
|
25
|
+
"*": {
|
|
26
|
+
"types": [
|
|
27
|
+
"dist/types/src/types.d.ts"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
17
31
|
"files": [
|
|
18
32
|
"dist",
|
|
19
33
|
"schema",
|
|
@@ -26,29 +40,28 @@
|
|
|
26
40
|
"express": "^4.19.2",
|
|
27
41
|
"get-port-please": "^3.1.1",
|
|
28
42
|
"ws": "^8.14.2",
|
|
29
|
-
"@braneframe/types": "0.5.3-main.
|
|
30
|
-
"@dxos/async": "0.5.3-main.
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/
|
|
34
|
-
"@dxos/echo-schema": "0.5.3-main.
|
|
35
|
-
"@dxos/invariant": "0.5.3-main.
|
|
36
|
-
"@dxos/keys": "0.5.3-main.
|
|
37
|
-
"@dxos/
|
|
38
|
-
"@dxos/
|
|
39
|
-
"@dxos/
|
|
40
|
-
"@dxos/util": "0.5.3-main.
|
|
43
|
+
"@braneframe/types": "0.5.3-main.7e64682",
|
|
44
|
+
"@dxos/async": "0.5.3-main.7e64682",
|
|
45
|
+
"@dxos/client": "0.5.3-main.7e64682",
|
|
46
|
+
"@dxos/context": "0.5.3-main.7e64682",
|
|
47
|
+
"@dxos/echo-db": "0.5.3-main.7e64682",
|
|
48
|
+
"@dxos/echo-schema": "0.5.3-main.7e64682",
|
|
49
|
+
"@dxos/invariant": "0.5.3-main.7e64682",
|
|
50
|
+
"@dxos/keys": "0.5.3-main.7e64682",
|
|
51
|
+
"@dxos/log": "0.5.3-main.7e64682",
|
|
52
|
+
"@dxos/protocols": "0.5.3-main.7e64682",
|
|
53
|
+
"@dxos/node-std": "0.5.3-main.7e64682",
|
|
54
|
+
"@dxos/util": "0.5.3-main.7e64682"
|
|
41
55
|
},
|
|
42
56
|
"devDependencies": {
|
|
43
57
|
"@types/express": "^4.17.17",
|
|
44
58
|
"@types/ws": "^7.4.0",
|
|
45
|
-
"@dxos/agent": "0.5.3-main.
|
|
59
|
+
"@dxos/agent": "0.5.3-main.7e64682"
|
|
46
60
|
},
|
|
47
61
|
"publishConfig": {
|
|
48
62
|
"access": "public"
|
|
49
63
|
},
|
|
50
64
|
"scripts": {
|
|
51
|
-
"gen-schema": "ts-node ./tools/schema.ts"
|
|
52
|
-
"prebuild": "pnpm gen-schema"
|
|
65
|
+
"gen-schema": "ts-node ./tools/schema.ts"
|
|
53
66
|
}
|
|
54
67
|
}
|
package/schema/functions.json
CHANGED
|
@@ -48,17 +48,16 @@
|
|
|
48
48
|
"properties": {
|
|
49
49
|
"function": {
|
|
50
50
|
"type": "string",
|
|
51
|
-
"description": "Function
|
|
51
|
+
"description": "Function URI.",
|
|
52
52
|
"title": "string"
|
|
53
53
|
},
|
|
54
|
+
"enabled": {
|
|
55
|
+
"type": "boolean",
|
|
56
|
+
"description": "a boolean",
|
|
57
|
+
"title": "boolean"
|
|
58
|
+
},
|
|
54
59
|
"meta": {
|
|
55
|
-
"
|
|
56
|
-
"required": [],
|
|
57
|
-
"properties": {},
|
|
58
|
-
"additionalProperties": {
|
|
59
|
-
"$id": "/schemas/any",
|
|
60
|
-
"title": "any"
|
|
61
|
-
}
|
|
60
|
+
"$ref": "#/$defs/object"
|
|
62
61
|
},
|
|
63
62
|
"spec": {
|
|
64
63
|
"anyOf": [
|
|
@@ -193,5 +192,20 @@
|
|
|
193
192
|
}
|
|
194
193
|
}
|
|
195
194
|
},
|
|
196
|
-
"additionalProperties": false
|
|
195
|
+
"additionalProperties": false,
|
|
196
|
+
"$defs": {
|
|
197
|
+
"object": {
|
|
198
|
+
"$id": "/schemas/object",
|
|
199
|
+
"oneOf": [
|
|
200
|
+
{
|
|
201
|
+
"type": "object"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"type": "array"
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
"description": "an object in the TypeScript meaning, i.e. the `object` type",
|
|
208
|
+
"title": "object"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
197
211
|
}
|
|
@@ -44,7 +44,7 @@ describe('function registry', () => {
|
|
|
44
44
|
const client = (await createInitializedClients(testBuilder))[0];
|
|
45
45
|
const registry = createRegistry(client);
|
|
46
46
|
const space = await client.spaces.create();
|
|
47
|
-
await registry.register(space, testManifest);
|
|
47
|
+
await registry.register(space, testManifest.functions);
|
|
48
48
|
const { objects: definitions } = await space.db.query(Filter.schema(FunctionDef)).run();
|
|
49
49
|
expect(definitions.length).to.eq(1);
|
|
50
50
|
expect(definitions[0].uri).to.eq(testManifest.functions?.[0]?.uri);
|
|
@@ -54,8 +54,8 @@ describe('function registry', () => {
|
|
|
54
54
|
const client = (await createInitializedClients(testBuilder))[0];
|
|
55
55
|
const registry = createRegistry(client);
|
|
56
56
|
const space = await client.spaces.create();
|
|
57
|
-
const existing = space.db.add(create(FunctionDef,
|
|
58
|
-
await registry.register(space, testManifest);
|
|
57
|
+
const existing = space.db.add(create(FunctionDef, testManifest.functions![0]));
|
|
58
|
+
await registry.register(space, testManifest.functions);
|
|
59
59
|
const { objects: definitions } = await space.db.query(Filter.schema(FunctionDef)).run();
|
|
60
60
|
expect(definitions.length).to.eq(1);
|
|
61
61
|
expect(definitions[0].uri).to.eq(existing.uri);
|
|
@@ -67,12 +67,12 @@ describe('function registry', () => {
|
|
|
67
67
|
const client = (await createInitializedClients(testBuilder))[0];
|
|
68
68
|
const registry = createRegistry(client);
|
|
69
69
|
const space = await client.spaces.create();
|
|
70
|
-
const definitions = range(3, () => create(FunctionDef,
|
|
70
|
+
const definitions = range(3, () => create(FunctionDef, testManifest.functions![0]));
|
|
71
71
|
definitions.forEach((def) => space.db.add(def));
|
|
72
72
|
|
|
73
73
|
const functionRegistered = new Trigger<FunctionDef[]>();
|
|
74
|
-
registry.
|
|
75
|
-
functionRegistered.wake(fn.
|
|
74
|
+
registry.registered.on((fn) => {
|
|
75
|
+
functionRegistered.wake(fn.added);
|
|
76
76
|
});
|
|
77
77
|
void registry.open(ctx);
|
|
78
78
|
const functions = await functionRegistered.wait();
|
|
@@ -86,12 +86,12 @@ describe('function registry', () => {
|
|
|
86
86
|
const space = await client.spaces.create();
|
|
87
87
|
|
|
88
88
|
const functionRegistered = new Trigger<FunctionDef>();
|
|
89
|
-
registry.
|
|
90
|
-
expect(fn.
|
|
91
|
-
functionRegistered.wake(fn.
|
|
89
|
+
registry.registered.on((fn) => {
|
|
90
|
+
expect(fn.added.length).to.eq(1);
|
|
91
|
+
functionRegistered.wake(fn.added[0]);
|
|
92
92
|
});
|
|
93
93
|
await registry.open(ctx);
|
|
94
|
-
await registry.register(space, testManifest);
|
|
94
|
+
await registry.register(space, testManifest.functions);
|
|
95
95
|
const registered = await functionRegistered.wait();
|
|
96
96
|
expect(registered.uri).to.eq(testManifest.functions![0].uri);
|
|
97
97
|
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Event } from '@dxos/async';
|
|
6
|
+
import { type Client } from '@dxos/client';
|
|
7
|
+
import { create, Filter, type Space } from '@dxos/client/echo';
|
|
8
|
+
import { type Context, Resource } from '@dxos/context';
|
|
9
|
+
import { PublicKey } from '@dxos/keys';
|
|
10
|
+
import { log } from '@dxos/log';
|
|
11
|
+
import { ComplexMap, diff } from '@dxos/util';
|
|
12
|
+
|
|
13
|
+
import { FunctionDef, type FunctionManifest } from '../types';
|
|
14
|
+
|
|
15
|
+
export type FunctionsRegisteredEvent = {
|
|
16
|
+
space: Space;
|
|
17
|
+
added: FunctionDef[];
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export class FunctionRegistry extends Resource {
|
|
21
|
+
private readonly _functionBySpaceKey = new ComplexMap<PublicKey, FunctionDef[]>(PublicKey.hash);
|
|
22
|
+
|
|
23
|
+
public readonly registered = new Event<FunctionsRegisteredEvent>();
|
|
24
|
+
|
|
25
|
+
constructor(private readonly _client: Client) {
|
|
26
|
+
super();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public getFunctions(space: Space): FunctionDef[] {
|
|
30
|
+
return this._functionBySpaceKey.get(space.key) ?? [];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Loads function definitions from the manifest into the space.
|
|
35
|
+
* We first load all the definitions from the space to deduplicate by functionId.
|
|
36
|
+
*/
|
|
37
|
+
public async register(space: Space, functions: FunctionManifest['functions']): Promise<void> {
|
|
38
|
+
log('register', { space: space.key, functions: functions?.length ?? 0 });
|
|
39
|
+
if (!functions?.length) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (!space.db.graph.runtimeSchemaRegistry.hasSchema(FunctionDef)) {
|
|
43
|
+
space.db.graph.runtimeSchemaRegistry.registerSchema(FunctionDef);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Sync definitions.
|
|
47
|
+
const { objects: existing } = await space.db.query(Filter.schema(FunctionDef)).run();
|
|
48
|
+
const { added } = diff(existing, functions, (a, b) => a.uri === b.uri);
|
|
49
|
+
// TODO(burdon): Update existing templates.
|
|
50
|
+
added.forEach((def) => space.db.add(create(FunctionDef, def)));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
protected override async _open(): Promise<void> {
|
|
54
|
+
log.info('opening...');
|
|
55
|
+
const spacesSubscription = this._client.spaces.subscribe(async (spaces) => {
|
|
56
|
+
for (const space of spaces) {
|
|
57
|
+
if (this._functionBySpaceKey.has(space.key)) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const registered: FunctionDef[] = [];
|
|
62
|
+
this._functionBySpaceKey.set(space.key, registered);
|
|
63
|
+
await space.waitUntilReady();
|
|
64
|
+
if (this._ctx.disposed) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Subscribe to updates.
|
|
69
|
+
this._ctx.onDispose(
|
|
70
|
+
space.db.query(Filter.schema(FunctionDef)).subscribe(({ objects }) => {
|
|
71
|
+
const { added } = diff(registered, objects, (a, b) => a.uri === b.uri);
|
|
72
|
+
// TODO(burdon): Update and remove.
|
|
73
|
+
if (added.length > 0) {
|
|
74
|
+
registered.push(...added);
|
|
75
|
+
this.registered.emit({ space, added });
|
|
76
|
+
}
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// TODO(burdon): API: Normalize unsubscribe methods.
|
|
83
|
+
this._ctx.onDispose(() => spacesSubscription.unsubscribe());
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
protected override async _close(_: Context): Promise<void> {
|
|
87
|
+
log.info('closing...');
|
|
88
|
+
this._functionBySpaceKey.clear();
|
|
89
|
+
}
|
|
90
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { TestBuilder } from '@dxos/client/testing';
|
|
|
11
11
|
import { describe, test } from '@dxos/test';
|
|
12
12
|
|
|
13
13
|
import { DevServer } from './dev-server';
|
|
14
|
-
import { FunctionRegistry } from '../
|
|
14
|
+
import { FunctionRegistry } from '../function';
|
|
15
15
|
import { createFunctionRuntime } from '../testing';
|
|
16
16
|
import { type FunctionManifest } from '../types';
|
|
17
17
|
|
|
@@ -44,7 +44,7 @@ describe('dev server', () => {
|
|
|
44
44
|
baseDir: path.join(__dirname, '../testing'),
|
|
45
45
|
});
|
|
46
46
|
const space = await client.spaces.create();
|
|
47
|
-
await registry.register(space, manifest);
|
|
47
|
+
await registry.register(space, manifest.functions);
|
|
48
48
|
await server.start();
|
|
49
49
|
|
|
50
50
|
// TODO(burdon): Doesn't shut down cleanly.
|
|
@@ -13,8 +13,8 @@ import { Context } from '@dxos/context';
|
|
|
13
13
|
import { invariant } from '@dxos/invariant';
|
|
14
14
|
import { log } from '@dxos/log';
|
|
15
15
|
|
|
16
|
+
import { type FunctionRegistry } from '../function';
|
|
16
17
|
import { type FunctionContext, type FunctionEvent, type FunctionHandler, type FunctionResponse } from '../handler';
|
|
17
|
-
import { type FunctionRegistry } from '../registry';
|
|
18
18
|
import { type FunctionDef } from '../types';
|
|
19
19
|
|
|
20
20
|
export type DevServerOptions = {
|
|
@@ -41,16 +41,16 @@ export class DevServer {
|
|
|
41
41
|
|
|
42
42
|
public readonly update = new Event<number>();
|
|
43
43
|
|
|
44
|
-
// prettier-ignore
|
|
45
44
|
constructor(
|
|
46
45
|
private readonly _client: Client,
|
|
47
46
|
private readonly _functionsRegistry: FunctionRegistry,
|
|
48
47
|
private readonly _options: DevServerOptions,
|
|
49
48
|
) {
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
// TODO(burdon): Add/remove listener in start/stop.
|
|
50
|
+
this._functionsRegistry.registered.on(async ({ added }) => {
|
|
51
|
+
added.forEach((def) => this._load(def));
|
|
52
52
|
await this._safeUpdateRegistration();
|
|
53
|
-
log('new functions loaded', {
|
|
53
|
+
log('new functions loaded', { added });
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -158,7 +158,7 @@ export class DevServer {
|
|
|
158
158
|
/**
|
|
159
159
|
* Load function.
|
|
160
160
|
*/
|
|
161
|
-
private async _load(def: FunctionDef, force
|
|
161
|
+
private async _load(def: FunctionDef, force?: boolean | undefined) {
|
|
162
162
|
const { uri, route, handler } = def;
|
|
163
163
|
const filePath = join(this._options.baseDir, handler);
|
|
164
164
|
log.info('loading', { uri, force });
|
|
@@ -189,8 +189,8 @@ export class DevServer {
|
|
|
189
189
|
registrationId: this._functionServiceRegistration,
|
|
190
190
|
functions: this.functions.map(({ def: { id, route } }) => ({ id, route })),
|
|
191
191
|
});
|
|
192
|
-
} catch (
|
|
193
|
-
log.catch(
|
|
192
|
+
} catch (err) {
|
|
193
|
+
log.catch(err);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
@@ -212,7 +212,6 @@ export class DevServer {
|
|
|
212
212
|
private async _invoke(path: string, event: FunctionEvent) {
|
|
213
213
|
const { handler } = this._handlers[path] ?? {};
|
|
214
214
|
invariant(handler, `invalid path: ${path}`);
|
|
215
|
-
|
|
216
215
|
const context: FunctionContext = {
|
|
217
216
|
client: this._client,
|
|
218
217
|
dataDir: this._options.dataDir,
|