@dxos/functions 0.5.2 → 0.5.3-main.088a2c8
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/index.mjs +492 -146
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +488 -143
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/handler.d.ts +33 -12
- 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 +17 -6
- package/dist/types/src/runtime/dev-server.d.ts.map +1 -1
- package/dist/types/src/runtime/dev-server.test.d.ts +2 -0
- package/dist/types/src/runtime/dev-server.test.d.ts.map +1 -0
- package/dist/types/src/runtime/scheduler.d.ts +55 -7
- package/dist/types/src/runtime/scheduler.d.ts.map +1 -1
- package/dist/types/src/testing/test/handler.d.ts +3 -0
- package/dist/types/src/testing/test/handler.d.ts.map +1 -0
- package/dist/types/src/testing/test/index.d.ts +3 -0
- package/dist/types/src/testing/test/index.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +182 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/dist/types/tools/schema.d.ts +2 -0
- package/dist/types/tools/schema.d.ts.map +1 -0
- package/package.json +20 -11
- package/schema/functions.json +183 -0
- package/src/handler.ts +56 -26
- package/src/index.ts +1 -1
- package/src/runtime/dev-server.test.ts +80 -0
- package/src/runtime/dev-server.ts +74 -40
- package/src/runtime/scheduler.test.ts +163 -9
- package/src/runtime/scheduler.ts +228 -64
- package/src/testing/test/handler.ts +9 -0
- package/src/testing/test/index.ts +7 -0
- package/src/types.ts +87 -0
- package/dist/types/src/manifest.d.ts +0 -26
- package/dist/types/src/manifest.d.ts.map +0 -1
- package/src/manifest.ts +0 -42
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import * as S from '@effect/schema/Schema';
|
|
2
|
+
declare const TimerTriggerSchema: S.struct<{
|
|
3
|
+
cron: S.$string;
|
|
4
|
+
}>;
|
|
5
|
+
declare const WebhookTriggerSchema: S.mutable<S.struct<{
|
|
6
|
+
method: S.$string;
|
|
7
|
+
port: S.PropertySignature<"?:", number | undefined, never, "?:", number | undefined, never>;
|
|
8
|
+
}>>;
|
|
9
|
+
declare const WebsocketTriggerSchema: S.struct<{
|
|
10
|
+
url: S.$string;
|
|
11
|
+
init: S.PropertySignature<"?:", {
|
|
12
|
+
readonly [x: string]: any;
|
|
13
|
+
} | undefined, never, "?:", {
|
|
14
|
+
readonly [x: string]: any;
|
|
15
|
+
} | undefined, never>;
|
|
16
|
+
}>;
|
|
17
|
+
declare const SubscriptionTriggerSchema: S.struct<{
|
|
18
|
+
spaceKey: S.PropertySignature<"?:", string | undefined, never, "?:", string | undefined, never>;
|
|
19
|
+
filter: S.array<S.struct<{
|
|
20
|
+
type: S.$string;
|
|
21
|
+
props: S.PropertySignature<"?:", {
|
|
22
|
+
readonly [x: string]: any;
|
|
23
|
+
} | undefined, never, "?:", {
|
|
24
|
+
readonly [x: string]: any;
|
|
25
|
+
} | undefined, never>;
|
|
26
|
+
}>>;
|
|
27
|
+
options: S.PropertySignature<"?:", {
|
|
28
|
+
readonly deep?: boolean | undefined;
|
|
29
|
+
readonly delay?: number | undefined;
|
|
30
|
+
} | undefined, never, "?:", {
|
|
31
|
+
readonly deep?: boolean | undefined;
|
|
32
|
+
readonly delay?: number | undefined;
|
|
33
|
+
} | undefined, never>;
|
|
34
|
+
}>;
|
|
35
|
+
declare const FunctionTriggerSchema: S.struct<{
|
|
36
|
+
function: S.$string;
|
|
37
|
+
meta: S.PropertySignature<"?:", {
|
|
38
|
+
readonly [x: string]: any;
|
|
39
|
+
} | undefined, never, "?:", {
|
|
40
|
+
readonly [x: string]: any;
|
|
41
|
+
} | undefined, never>;
|
|
42
|
+
timer: S.PropertySignature<"?:", {
|
|
43
|
+
readonly cron: string;
|
|
44
|
+
} | undefined, never, "?:", {
|
|
45
|
+
readonly cron: string;
|
|
46
|
+
} | undefined, never>;
|
|
47
|
+
webhook: S.PropertySignature<"?:", {
|
|
48
|
+
port?: number | undefined;
|
|
49
|
+
method: string;
|
|
50
|
+
} | undefined, never, "?:", {
|
|
51
|
+
method: string;
|
|
52
|
+
port?: number | undefined;
|
|
53
|
+
} | undefined, never>;
|
|
54
|
+
websocket: S.PropertySignature<"?:", {
|
|
55
|
+
readonly url: string;
|
|
56
|
+
readonly init?: {
|
|
57
|
+
readonly [x: string]: any;
|
|
58
|
+
} | undefined;
|
|
59
|
+
} | undefined, never, "?:", {
|
|
60
|
+
readonly url: string;
|
|
61
|
+
readonly init?: {
|
|
62
|
+
readonly [x: string]: any;
|
|
63
|
+
} | undefined;
|
|
64
|
+
} | undefined, never>;
|
|
65
|
+
subscription: S.PropertySignature<"?:", {
|
|
66
|
+
readonly filter: readonly {
|
|
67
|
+
readonly type: string;
|
|
68
|
+
readonly props?: {
|
|
69
|
+
readonly [x: string]: any;
|
|
70
|
+
} | undefined;
|
|
71
|
+
}[];
|
|
72
|
+
readonly spaceKey?: string | undefined;
|
|
73
|
+
readonly options?: {
|
|
74
|
+
readonly deep?: boolean | undefined;
|
|
75
|
+
readonly delay?: number | undefined;
|
|
76
|
+
} | undefined;
|
|
77
|
+
} | undefined, never, "?:", {
|
|
78
|
+
readonly filter: readonly {
|
|
79
|
+
readonly type: string;
|
|
80
|
+
readonly props?: {
|
|
81
|
+
readonly [x: string]: any;
|
|
82
|
+
} | undefined;
|
|
83
|
+
}[];
|
|
84
|
+
readonly spaceKey?: string | undefined;
|
|
85
|
+
readonly options?: {
|
|
86
|
+
readonly deep?: boolean | undefined;
|
|
87
|
+
readonly delay?: number | undefined;
|
|
88
|
+
} | undefined;
|
|
89
|
+
} | undefined, never>;
|
|
90
|
+
}>;
|
|
91
|
+
export type FunctionTrigger = S.Schema.Type<typeof FunctionTriggerSchema>;
|
|
92
|
+
export type TimerTrigger = S.Schema.Type<typeof TimerTriggerSchema>;
|
|
93
|
+
export type WebhookTrigger = S.Schema.Type<typeof WebhookTriggerSchema>;
|
|
94
|
+
export type WebsocketTrigger = S.Schema.Type<typeof WebsocketTriggerSchema>;
|
|
95
|
+
export type SubscriptionTrigger = S.Schema.Type<typeof SubscriptionTriggerSchema>;
|
|
96
|
+
/**
|
|
97
|
+
* Function definition.
|
|
98
|
+
*/
|
|
99
|
+
declare const FunctionDefSchema: S.struct<{
|
|
100
|
+
id: S.$string;
|
|
101
|
+
description: S.PropertySignature<"?:", string | undefined, never, "?:", string | undefined, never>;
|
|
102
|
+
path: S.$string;
|
|
103
|
+
handler: S.$string;
|
|
104
|
+
}>;
|
|
105
|
+
export type FunctionDef = S.Schema.Type<typeof FunctionDefSchema>;
|
|
106
|
+
/**
|
|
107
|
+
* Function manifest file.
|
|
108
|
+
*/
|
|
109
|
+
export declare const FunctionManifestSchema: S.struct<{
|
|
110
|
+
functions: S.mutable<S.array<S.struct<{
|
|
111
|
+
id: S.$string;
|
|
112
|
+
description: S.PropertySignature<"?:", string | undefined, never, "?:", string | undefined, never>;
|
|
113
|
+
path: S.$string;
|
|
114
|
+
handler: S.$string;
|
|
115
|
+
}>>>;
|
|
116
|
+
triggers: S.PropertySignature<"?:", {
|
|
117
|
+
readonly function: string;
|
|
118
|
+
readonly meta?: {
|
|
119
|
+
readonly [x: string]: any;
|
|
120
|
+
} | undefined;
|
|
121
|
+
readonly timer?: {
|
|
122
|
+
readonly cron: string;
|
|
123
|
+
} | undefined;
|
|
124
|
+
readonly webhook?: {
|
|
125
|
+
port?: number | undefined;
|
|
126
|
+
method: string;
|
|
127
|
+
} | undefined;
|
|
128
|
+
readonly websocket?: {
|
|
129
|
+
readonly url: string;
|
|
130
|
+
readonly init?: {
|
|
131
|
+
readonly [x: string]: any;
|
|
132
|
+
} | undefined;
|
|
133
|
+
} | undefined;
|
|
134
|
+
readonly subscription?: {
|
|
135
|
+
readonly filter: readonly {
|
|
136
|
+
readonly type: string;
|
|
137
|
+
readonly props?: {
|
|
138
|
+
readonly [x: string]: any;
|
|
139
|
+
} | undefined;
|
|
140
|
+
}[];
|
|
141
|
+
readonly spaceKey?: string | undefined;
|
|
142
|
+
readonly options?: {
|
|
143
|
+
readonly deep?: boolean | undefined;
|
|
144
|
+
readonly delay?: number | undefined;
|
|
145
|
+
} | undefined;
|
|
146
|
+
} | undefined;
|
|
147
|
+
}[] | undefined, never, "?:", {
|
|
148
|
+
readonly function: string;
|
|
149
|
+
readonly meta?: {
|
|
150
|
+
readonly [x: string]: any;
|
|
151
|
+
} | undefined;
|
|
152
|
+
readonly timer?: {
|
|
153
|
+
readonly cron: string;
|
|
154
|
+
} | undefined;
|
|
155
|
+
readonly webhook?: {
|
|
156
|
+
method: string;
|
|
157
|
+
port?: number | undefined;
|
|
158
|
+
} | undefined;
|
|
159
|
+
readonly websocket?: {
|
|
160
|
+
readonly url: string;
|
|
161
|
+
readonly init?: {
|
|
162
|
+
readonly [x: string]: any;
|
|
163
|
+
} | undefined;
|
|
164
|
+
} | undefined;
|
|
165
|
+
readonly subscription?: {
|
|
166
|
+
readonly filter: readonly {
|
|
167
|
+
readonly type: string;
|
|
168
|
+
readonly props?: {
|
|
169
|
+
readonly [x: string]: any;
|
|
170
|
+
} | undefined;
|
|
171
|
+
}[];
|
|
172
|
+
readonly spaceKey?: string | undefined;
|
|
173
|
+
readonly options?: {
|
|
174
|
+
readonly deep?: boolean | undefined;
|
|
175
|
+
readonly delay?: number | undefined;
|
|
176
|
+
} | undefined;
|
|
177
|
+
} | undefined;
|
|
178
|
+
}[] | undefined, never>;
|
|
179
|
+
}>;
|
|
180
|
+
export type FunctionManifest = S.Schema.Type<typeof FunctionManifestSchema>;
|
|
181
|
+
export {};
|
|
182
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,CAAC,MAAM,uBAAuB,CAAC;AAE3C,QAAA,MAAM,kBAAkB;;EAEtB,CAAC;AAEH,QAAA,MAAM,oBAAoB;;;GAMzB,CAAC;AAEF,QAAA,MAAM,sBAAsB;;;;;;;EAG1B,CAAC;AAEH,QAAA,MAAM,yBAAyB;;;;;;;;;;;;;;;;;EAiB7B,CAAC;AAEH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWzB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACpE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACxE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC5E,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAElF;;GAEG;AAEH,QAAA,MAAM,iBAAiB;;;;;EAQrB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../tools/schema.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/functions",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3-main.088a2c8",
|
|
4
4
|
"description": "Functions SDK and runtime.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -16,27 +16,36 @@
|
|
|
16
16
|
"types": "dist/types/src/index.d.ts",
|
|
17
17
|
"files": [
|
|
18
18
|
"dist",
|
|
19
|
+
"schema",
|
|
19
20
|
"src"
|
|
20
21
|
],
|
|
21
22
|
"dependencies": {
|
|
23
|
+
"@effect/schema": "^0.64.20",
|
|
22
24
|
"@preact/signals-core": "^1.6.0",
|
|
23
25
|
"cron": "^3.1.6",
|
|
26
|
+
"effect": "^2.4.19",
|
|
24
27
|
"express": "^4.19.2",
|
|
25
28
|
"get-port-please": "^3.1.1",
|
|
26
|
-
"
|
|
27
|
-
"@
|
|
28
|
-
"@dxos/
|
|
29
|
-
"@dxos/context": "0.5.
|
|
30
|
-
"@dxos/echo-schema": "0.5.
|
|
31
|
-
"@dxos/invariant": "0.5.
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/node-std": "0.5.
|
|
34
|
-
"@dxos/
|
|
29
|
+
"ws": "^8.14.2",
|
|
30
|
+
"@braneframe/types": "0.5.3-main.088a2c8",
|
|
31
|
+
"@dxos/async": "0.5.3-main.088a2c8",
|
|
32
|
+
"@dxos/context": "0.5.3-main.088a2c8",
|
|
33
|
+
"@dxos/echo-schema": "0.5.3-main.088a2c8",
|
|
34
|
+
"@dxos/invariant": "0.5.3-main.088a2c8",
|
|
35
|
+
"@dxos/client": "0.5.3-main.088a2c8",
|
|
36
|
+
"@dxos/node-std": "0.5.3-main.088a2c8",
|
|
37
|
+
"@dxos/log": "0.5.3-main.088a2c8",
|
|
38
|
+
"@dxos/util": "0.5.3-main.088a2c8"
|
|
35
39
|
},
|
|
36
40
|
"devDependencies": {
|
|
37
|
-
"@types/express": "^4.17.17"
|
|
41
|
+
"@types/express": "^4.17.17",
|
|
42
|
+
"@types/ws": "^7.4.0",
|
|
43
|
+
"@dxos/agent": "0.5.3-main.088a2c8"
|
|
38
44
|
},
|
|
39
45
|
"publishConfig": {
|
|
40
46
|
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"gen-schema": "ts-node ./tools/schema.ts"
|
|
41
50
|
}
|
|
42
51
|
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"required": [
|
|
5
|
+
"functions"
|
|
6
|
+
],
|
|
7
|
+
"properties": {
|
|
8
|
+
"functions": {
|
|
9
|
+
"type": "array",
|
|
10
|
+
"items": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"required": [
|
|
13
|
+
"id",
|
|
14
|
+
"path",
|
|
15
|
+
"handler"
|
|
16
|
+
],
|
|
17
|
+
"properties": {
|
|
18
|
+
"id": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "a string",
|
|
21
|
+
"title": "string"
|
|
22
|
+
},
|
|
23
|
+
"path": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "a string",
|
|
26
|
+
"title": "string"
|
|
27
|
+
},
|
|
28
|
+
"handler": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"description": "a string",
|
|
31
|
+
"title": "string"
|
|
32
|
+
},
|
|
33
|
+
"description": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "a string",
|
|
36
|
+
"title": "string"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"additionalProperties": false
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"triggers": {
|
|
43
|
+
"type": "array",
|
|
44
|
+
"items": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"required": [
|
|
47
|
+
"function"
|
|
48
|
+
],
|
|
49
|
+
"properties": {
|
|
50
|
+
"function": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "Function ID/URI.",
|
|
53
|
+
"title": "string"
|
|
54
|
+
},
|
|
55
|
+
"meta": {
|
|
56
|
+
"type": "object",
|
|
57
|
+
"required": [],
|
|
58
|
+
"properties": {},
|
|
59
|
+
"additionalProperties": {
|
|
60
|
+
"$id": "/schemas/any",
|
|
61
|
+
"title": "any"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"timer": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"required": [
|
|
67
|
+
"cron"
|
|
68
|
+
],
|
|
69
|
+
"properties": {
|
|
70
|
+
"cron": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"description": "a string",
|
|
73
|
+
"title": "string"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"additionalProperties": false
|
|
77
|
+
},
|
|
78
|
+
"webhook": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"required": [
|
|
81
|
+
"method"
|
|
82
|
+
],
|
|
83
|
+
"properties": {
|
|
84
|
+
"method": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"description": "a string",
|
|
87
|
+
"title": "string"
|
|
88
|
+
},
|
|
89
|
+
"port": {
|
|
90
|
+
"type": "number",
|
|
91
|
+
"description": "a number",
|
|
92
|
+
"title": "number"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"additionalProperties": false
|
|
96
|
+
},
|
|
97
|
+
"websocket": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"required": [
|
|
100
|
+
"url"
|
|
101
|
+
],
|
|
102
|
+
"properties": {
|
|
103
|
+
"url": {
|
|
104
|
+
"type": "string",
|
|
105
|
+
"description": "a string",
|
|
106
|
+
"title": "string"
|
|
107
|
+
},
|
|
108
|
+
"init": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"required": [],
|
|
111
|
+
"properties": {},
|
|
112
|
+
"additionalProperties": {
|
|
113
|
+
"$id": "/schemas/any",
|
|
114
|
+
"title": "any"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"additionalProperties": false
|
|
119
|
+
},
|
|
120
|
+
"subscription": {
|
|
121
|
+
"type": "object",
|
|
122
|
+
"required": [
|
|
123
|
+
"filter"
|
|
124
|
+
],
|
|
125
|
+
"properties": {
|
|
126
|
+
"spaceKey": {
|
|
127
|
+
"type": "string",
|
|
128
|
+
"description": "a string",
|
|
129
|
+
"title": "string"
|
|
130
|
+
},
|
|
131
|
+
"filter": {
|
|
132
|
+
"type": "array",
|
|
133
|
+
"items": {
|
|
134
|
+
"type": "object",
|
|
135
|
+
"required": [
|
|
136
|
+
"type"
|
|
137
|
+
],
|
|
138
|
+
"properties": {
|
|
139
|
+
"type": {
|
|
140
|
+
"type": "string",
|
|
141
|
+
"description": "a string",
|
|
142
|
+
"title": "string"
|
|
143
|
+
},
|
|
144
|
+
"props": {
|
|
145
|
+
"type": "object",
|
|
146
|
+
"required": [],
|
|
147
|
+
"properties": {},
|
|
148
|
+
"additionalProperties": {
|
|
149
|
+
"$id": "/schemas/any",
|
|
150
|
+
"title": "any"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"additionalProperties": false
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"options": {
|
|
158
|
+
"type": "object",
|
|
159
|
+
"required": [],
|
|
160
|
+
"properties": {
|
|
161
|
+
"deep": {
|
|
162
|
+
"type": "boolean",
|
|
163
|
+
"description": "a boolean",
|
|
164
|
+
"title": "boolean"
|
|
165
|
+
},
|
|
166
|
+
"delay": {
|
|
167
|
+
"type": "number",
|
|
168
|
+
"description": "a number",
|
|
169
|
+
"title": "number"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"additionalProperties": false
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
"additionalProperties": false
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
"additionalProperties": false
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"additionalProperties": false
|
|
183
|
+
}
|
package/src/handler.ts
CHANGED
|
@@ -8,31 +8,61 @@ import { type EchoReactiveObject } from '@dxos/echo-schema';
|
|
|
8
8
|
import { log } from '@dxos/log';
|
|
9
9
|
import { nonNullable } from '@dxos/util';
|
|
10
10
|
|
|
11
|
-
// TODO(burdon):
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
// TODO(burdon): Model after http request. Ref Lambda/OpenFaaS.
|
|
12
|
+
// https://docs.aws.amazon.com/lambda/latest/dg/typescript-handler.html
|
|
13
|
+
// https://www.serverless.com/framework/docs/providers/aws/guide/serverless.yml/#functions
|
|
14
|
+
// https://www.npmjs.com/package/aws-lambda
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Function handler.
|
|
18
|
+
*/
|
|
19
|
+
export type FunctionHandler<TData = {}, TMeta = {}> = (params: {
|
|
20
|
+
context: FunctionContext;
|
|
21
|
+
event: FunctionEvent<TData, TMeta>;
|
|
22
|
+
response: FunctionResponse;
|
|
23
|
+
}) => Promise<FunctionResponse | void>;
|
|
15
24
|
|
|
16
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Function context.
|
|
27
|
+
*/
|
|
17
28
|
export interface FunctionContext {
|
|
29
|
+
// TODO(burdon): Limit access to individual space.
|
|
18
30
|
client: Client;
|
|
31
|
+
// TODO(burdon): Replace with storage service abstraction.
|
|
19
32
|
dataDir?: string;
|
|
20
33
|
}
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Event payload.
|
|
37
|
+
*/
|
|
38
|
+
export type FunctionEvent<TData = {}, TMeta = {}> = {
|
|
39
|
+
data: FunctionEventMeta<TMeta> & TData;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Metadata from trigger.
|
|
44
|
+
*/
|
|
45
|
+
export type FunctionEventMeta<TMeta = {}> = {
|
|
46
|
+
meta: TMeta;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Function response.
|
|
51
|
+
*/
|
|
52
|
+
export interface FunctionResponse {
|
|
53
|
+
status(code: number): FunctionResponse;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//
|
|
57
|
+
// Subscription utils.
|
|
58
|
+
//
|
|
29
59
|
|
|
30
|
-
export type
|
|
31
|
-
|
|
60
|
+
export type RawSubscriptionData = {
|
|
61
|
+
spaceKey?: string;
|
|
32
62
|
objects?: string[];
|
|
33
63
|
};
|
|
34
64
|
|
|
35
|
-
export type
|
|
65
|
+
export type SubscriptionData = {
|
|
36
66
|
space?: Space;
|
|
37
67
|
objects?: EchoReactiveObject<any>[];
|
|
38
68
|
};
|
|
@@ -47,22 +77,22 @@ export type FunctionSubscriptionEvent2 = {
|
|
|
47
77
|
*
|
|
48
78
|
* NOTE: Get space key from devtools or `dx space list --json`
|
|
49
79
|
*/
|
|
50
|
-
export const subscriptionHandler = (
|
|
51
|
-
handler: FunctionHandler<
|
|
52
|
-
): FunctionHandler<
|
|
53
|
-
return ({ event, context, ...rest }) => {
|
|
80
|
+
export const subscriptionHandler = <TMeta>(
|
|
81
|
+
handler: FunctionHandler<SubscriptionData, TMeta>,
|
|
82
|
+
): FunctionHandler<RawSubscriptionData, TMeta> => {
|
|
83
|
+
return ({ event: { data }, context, ...rest }) => {
|
|
54
84
|
const { client } = context;
|
|
55
|
-
const space =
|
|
56
|
-
const objects =
|
|
57
|
-
space
|
|
58
|
-
|
|
85
|
+
const space = data.spaceKey ? client.spaces.get(PublicKey.from(data.spaceKey)) : undefined;
|
|
86
|
+
const objects = space
|
|
87
|
+
? data.objects?.map<EchoReactiveObject<any> | undefined>((id) => space!.db.getObjectById(id)).filter(nonNullable)
|
|
88
|
+
: [];
|
|
59
89
|
|
|
60
|
-
if (!!
|
|
61
|
-
log.warn('invalid space', {
|
|
90
|
+
if (!!data.spaceKey && !space) {
|
|
91
|
+
log.warn('invalid space', { data });
|
|
62
92
|
} else {
|
|
63
93
|
log.info('handler', { space: space?.key.truncate(), objects: objects?.length });
|
|
64
94
|
}
|
|
65
95
|
|
|
66
|
-
return handler({ event: { space, objects }, context, ...rest });
|
|
96
|
+
return handler({ event: { data: { ...data, space, objects } }, context, ...rest });
|
|
67
97
|
};
|
|
68
98
|
};
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { expect } from 'chai';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
|
|
8
|
+
import { FunctionsPlugin } from '@dxos/agent';
|
|
9
|
+
import { Client, Config } from '@dxos/client';
|
|
10
|
+
import { TestBuilder } from '@dxos/client/testing';
|
|
11
|
+
import { describe, openAndClose, test } from '@dxos/test';
|
|
12
|
+
|
|
13
|
+
import { DevServer } from './dev-server';
|
|
14
|
+
import { type FunctionManifest } from '../types';
|
|
15
|
+
|
|
16
|
+
describe('dev server', () => {
|
|
17
|
+
let client: Client;
|
|
18
|
+
let testBuilder: TestBuilder;
|
|
19
|
+
before(async () => {
|
|
20
|
+
testBuilder = new TestBuilder();
|
|
21
|
+
const config = new Config({
|
|
22
|
+
runtime: {
|
|
23
|
+
agent: {
|
|
24
|
+
plugins: [
|
|
25
|
+
{
|
|
26
|
+
id: 'dxos.org/agent/plugin/functions',
|
|
27
|
+
config: {
|
|
28
|
+
port: 8080,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const services = testBuilder.createLocalClientServices();
|
|
37
|
+
client = new Client({ config, services });
|
|
38
|
+
|
|
39
|
+
await client.initialize();
|
|
40
|
+
await client.halo.createIdentity();
|
|
41
|
+
testBuilder.ctx.onDispose(() => client.destroy());
|
|
42
|
+
|
|
43
|
+
// TODO(burdon): Better way to configure plugin? (Rationalize chess.test).
|
|
44
|
+
const functionsPlugin = new FunctionsPlugin();
|
|
45
|
+
await functionsPlugin.initialize({ client, clientServices: services });
|
|
46
|
+
await openAndClose(functionsPlugin);
|
|
47
|
+
|
|
48
|
+
expect(client.services.services.FunctionRegistryService).to.exist;
|
|
49
|
+
});
|
|
50
|
+
after(async () => {
|
|
51
|
+
await testBuilder.destroy();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('start/stop', async () => {
|
|
55
|
+
const manifest: FunctionManifest = {
|
|
56
|
+
functions: [
|
|
57
|
+
{
|
|
58
|
+
id: 'example.com/function/test',
|
|
59
|
+
path: 'test',
|
|
60
|
+
handler: 'test',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const server = new DevServer(client, {
|
|
66
|
+
manifest,
|
|
67
|
+
baseDir: path.join(__dirname, '../testing'),
|
|
68
|
+
});
|
|
69
|
+
await server.initialize();
|
|
70
|
+
await server.start();
|
|
71
|
+
|
|
72
|
+
// TODO(burdon): Doesn't shut down cleanly.
|
|
73
|
+
// Error: invariant violation [this._client.services.services.FunctionRegistryService]
|
|
74
|
+
testBuilder.ctx.onDispose(() => server.stop());
|
|
75
|
+
expect(server).to.exist;
|
|
76
|
+
|
|
77
|
+
await server.invoke('test', {});
|
|
78
|
+
expect(server.stats.seq).to.eq(1);
|
|
79
|
+
});
|
|
80
|
+
});
|