@dxos/functions 0.8.2-main.12df754 → 0.8.2-main.2f9c567

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.
Files changed (168) hide show
  1. package/dist/lib/browser/bundler/index.mjs +0 -3
  2. package/dist/lib/browser/bundler/index.mjs.map +1 -1
  3. package/dist/lib/browser/edge/index.mjs +63 -7
  4. package/dist/lib/browser/edge/index.mjs.map +4 -4
  5. package/dist/lib/browser/index.mjs +367 -99
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/node/bundler/index.cjs +0 -1
  9. package/dist/lib/node/bundler/index.cjs.map +1 -1
  10. package/dist/lib/node/edge/index.cjs +65 -5
  11. package/dist/lib/node/edge/index.cjs.map +4 -4
  12. package/dist/lib/node/index.cjs +382 -94
  13. package/dist/lib/node/index.cjs.map +4 -4
  14. package/dist/lib/node/meta.json +1 -1
  15. package/dist/lib/node-esm/bundler/index.mjs +0 -1
  16. package/dist/lib/node-esm/bundler/index.mjs.map +1 -1
  17. package/dist/lib/node-esm/edge/index.mjs +64 -6
  18. package/dist/lib/node-esm/edge/index.mjs.map +4 -4
  19. package/dist/lib/node-esm/index.mjs +367 -97
  20. package/dist/lib/node-esm/index.mjs.map +4 -4
  21. package/dist/lib/node-esm/meta.json +1 -1
  22. package/dist/types/src/edge/index.d.ts.map +1 -1
  23. package/dist/types/src/handler.d.ts +12 -61
  24. package/dist/types/src/handler.d.ts.map +1 -1
  25. package/dist/types/src/index.d.ts +3 -3
  26. package/dist/types/src/index.d.ts.map +1 -1
  27. package/dist/types/src/schema.d.ts +57 -0
  28. package/dist/types/src/schema.d.ts.map +1 -0
  29. package/dist/types/src/trace.d.ts +148 -0
  30. package/dist/types/src/trace.d.ts.map +1 -0
  31. package/dist/types/src/{types/types.d.ts → types.d.ts} +191 -49
  32. package/dist/types/src/types.d.ts.map +1 -0
  33. package/dist/types/src/url.d.ts.map +1 -0
  34. package/package.json +20 -36
  35. package/src/edge/index.ts +4 -0
  36. package/src/handler.ts +14 -118
  37. package/src/index.ts +4 -5
  38. package/src/schema.ts +53 -0
  39. package/src/{types/trace.ts → trace.ts} +33 -31
  40. package/src/translations.ts +1 -1
  41. package/src/types.ts +214 -0
  42. package/dist/lib/browser/chunk-2YE6S7XY.mjs +0 -360
  43. package/dist/lib/browser/chunk-2YE6S7XY.mjs.map +0 -7
  44. package/dist/lib/browser/chunk-7CHDHCV3.mjs +0 -482
  45. package/dist/lib/browser/chunk-7CHDHCV3.mjs.map +0 -7
  46. package/dist/lib/browser/chunk-LT4LR4VU.mjs +0 -72
  47. package/dist/lib/browser/chunk-LT4LR4VU.mjs.map +0 -7
  48. package/dist/lib/browser/chunk-XRCXIG74.mjs +0 -12
  49. package/dist/lib/browser/chunk-XRCXIG74.mjs.map +0 -7
  50. package/dist/lib/browser/testing/index.mjs +0 -670
  51. package/dist/lib/browser/testing/index.mjs.map +0 -7
  52. package/dist/lib/browser/types/index.mjs +0 -51
  53. package/dist/lib/browser/types/index.mjs.map +0 -7
  54. package/dist/lib/node/chunk-FBIUZ7SD.cjs +0 -496
  55. package/dist/lib/node/chunk-FBIUZ7SD.cjs.map +0 -7
  56. package/dist/lib/node/chunk-JEQ2X3Z6.cjs +0 -34
  57. package/dist/lib/node/chunk-JEQ2X3Z6.cjs.map +0 -7
  58. package/dist/lib/node/chunk-NXZNXVT3.cjs +0 -94
  59. package/dist/lib/node/chunk-NXZNXVT3.cjs.map +0 -7
  60. package/dist/lib/node/chunk-SV5NRE5L.cjs +0 -395
  61. package/dist/lib/node/chunk-SV5NRE5L.cjs.map +0 -7
  62. package/dist/lib/node/testing/index.cjs +0 -687
  63. package/dist/lib/node/testing/index.cjs.map +0 -7
  64. package/dist/lib/node/types/index.cjs +0 -72
  65. package/dist/lib/node/types/index.cjs.map +0 -7
  66. package/dist/lib/node-esm/chunk-3XMJFSID.mjs +0 -360
  67. package/dist/lib/node-esm/chunk-3XMJFSID.mjs.map +0 -7
  68. package/dist/lib/node-esm/chunk-C6YINTWG.mjs +0 -482
  69. package/dist/lib/node-esm/chunk-C6YINTWG.mjs.map +0 -7
  70. package/dist/lib/node-esm/chunk-DHGBFXSZ.mjs +0 -12
  71. package/dist/lib/node-esm/chunk-DHGBFXSZ.mjs.map +0 -7
  72. package/dist/lib/node-esm/chunk-O2SXVYU5.mjs +0 -72
  73. package/dist/lib/node-esm/chunk-O2SXVYU5.mjs.map +0 -7
  74. package/dist/lib/node-esm/testing/index.mjs +0 -670
  75. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  76. package/dist/lib/node-esm/types/index.mjs +0 -51
  77. package/dist/lib/node-esm/types/index.mjs.map +0 -7
  78. package/dist/types/src/browser/index.d.ts +0 -2
  79. package/dist/types/src/browser/index.d.ts.map +0 -1
  80. package/dist/types/src/function/function-registry.d.ts +0 -25
  81. package/dist/types/src/function/function-registry.d.ts.map +0 -1
  82. package/dist/types/src/function/function-registry.test.d.ts +0 -2
  83. package/dist/types/src/function/function-registry.test.d.ts.map +0 -1
  84. package/dist/types/src/function/index.d.ts +0 -2
  85. package/dist/types/src/function/index.d.ts.map +0 -1
  86. package/dist/types/src/runtime/dev-server.d.ts +0 -52
  87. package/dist/types/src/runtime/dev-server.d.ts.map +0 -1
  88. package/dist/types/src/runtime/dev-server.test.d.ts +0 -2
  89. package/dist/types/src/runtime/dev-server.test.d.ts.map +0 -1
  90. package/dist/types/src/runtime/index.d.ts +0 -3
  91. package/dist/types/src/runtime/index.d.ts.map +0 -1
  92. package/dist/types/src/runtime/scheduler.d.ts +0 -34
  93. package/dist/types/src/runtime/scheduler.d.ts.map +0 -1
  94. package/dist/types/src/runtime/scheduler.test.d.ts +0 -2
  95. package/dist/types/src/runtime/scheduler.test.d.ts.map +0 -1
  96. package/dist/types/src/testing/functions-integration.test.d.ts +0 -2
  97. package/dist/types/src/testing/functions-integration.test.d.ts.map +0 -1
  98. package/dist/types/src/testing/index.d.ts +0 -5
  99. package/dist/types/src/testing/index.d.ts.map +0 -1
  100. package/dist/types/src/testing/manifest.d.ts +0 -3
  101. package/dist/types/src/testing/manifest.d.ts.map +0 -1
  102. package/dist/types/src/testing/plugin-init.d.ts +0 -6
  103. package/dist/types/src/testing/plugin-init.d.ts.map +0 -1
  104. package/dist/types/src/testing/setup.d.ts +0 -15
  105. package/dist/types/src/testing/setup.d.ts.map +0 -1
  106. package/dist/types/src/testing/test/handler.d.ts +0 -4
  107. package/dist/types/src/testing/test/handler.d.ts.map +0 -1
  108. package/dist/types/src/testing/test/index.d.ts +0 -3
  109. package/dist/types/src/testing/test/index.d.ts.map +0 -1
  110. package/dist/types/src/testing/types.d.ts +0 -10
  111. package/dist/types/src/testing/types.d.ts.map +0 -1
  112. package/dist/types/src/testing/util.d.ts +0 -5
  113. package/dist/types/src/testing/util.d.ts.map +0 -1
  114. package/dist/types/src/trigger/index.d.ts +0 -3
  115. package/dist/types/src/trigger/index.d.ts.map +0 -1
  116. package/dist/types/src/trigger/trigger-registry.d.ts +0 -38
  117. package/dist/types/src/trigger/trigger-registry.d.ts.map +0 -1
  118. package/dist/types/src/trigger/trigger-registry.test.d.ts +0 -2
  119. package/dist/types/src/trigger/trigger-registry.test.d.ts.map +0 -1
  120. package/dist/types/src/trigger/type/index.d.ts +0 -3
  121. package/dist/types/src/trigger/type/index.d.ts.map +0 -1
  122. package/dist/types/src/trigger/type/subscription-trigger.d.ts +0 -4
  123. package/dist/types/src/trigger/type/subscription-trigger.d.ts.map +0 -1
  124. package/dist/types/src/trigger/type/timer-trigger.d.ts +0 -4
  125. package/dist/types/src/trigger/type/timer-trigger.d.ts.map +0 -1
  126. package/dist/types/src/trigger/type/webhook-trigger.d.ts +0 -4
  127. package/dist/types/src/trigger/type/webhook-trigger.d.ts.map +0 -1
  128. package/dist/types/src/types/index.d.ts +0 -5
  129. package/dist/types/src/types/index.d.ts.map +0 -1
  130. package/dist/types/src/types/schema.d.ts +0 -53
  131. package/dist/types/src/types/schema.d.ts.map +0 -1
  132. package/dist/types/src/types/trace.d.ts +0 -146
  133. package/dist/types/src/types/trace.d.ts.map +0 -1
  134. package/dist/types/src/types/types.d.ts.map +0 -1
  135. package/dist/types/src/types/url.d.ts.map +0 -1
  136. package/dist/types/tools/schema.d.ts +0 -2
  137. package/dist/types/tools/schema.d.ts.map +0 -1
  138. package/schema/functions.json +0 -211
  139. package/src/browser/index.ts +0 -5
  140. package/src/function/function-registry.test.ts +0 -118
  141. package/src/function/function-registry.ts +0 -104
  142. package/src/function/index.ts +0 -5
  143. package/src/runtime/dev-server.test.ts +0 -79
  144. package/src/runtime/dev-server.ts +0 -240
  145. package/src/runtime/index.ts +0 -6
  146. package/src/runtime/scheduler.test.ts +0 -152
  147. package/src/runtime/scheduler.ts +0 -170
  148. package/src/testing/functions-integration.test.ts +0 -65
  149. package/src/testing/index.ts +0 -8
  150. package/src/testing/manifest.ts +0 -15
  151. package/src/testing/plugin-init.ts +0 -20
  152. package/src/testing/setup.ts +0 -109
  153. package/src/testing/test/handler.ts +0 -15
  154. package/src/testing/test/index.ts +0 -7
  155. package/src/testing/types.ts +0 -9
  156. package/src/testing/util.ts +0 -26
  157. package/src/trigger/index.ts +0 -6
  158. package/src/trigger/trigger-registry.test.ts +0 -278
  159. package/src/trigger/trigger-registry.ts +0 -218
  160. package/src/trigger/type/index.ts +0 -7
  161. package/src/trigger/type/subscription-trigger.ts +0 -84
  162. package/src/trigger/type/timer-trigger.ts +0 -48
  163. package/src/trigger/type/webhook-trigger.ts +0 -48
  164. package/src/types/index.ts +0 -8
  165. package/src/types/schema.ts +0 -46
  166. package/src/types/types.ts +0 -163
  167. /package/dist/types/src/{types/url.d.ts → url.d.ts} +0 -0
  168. /package/src/{types/url.ts → url.ts} +0 -0
@@ -1,65 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { afterAll, beforeAll, describe, expect, test } from 'vitest';
6
-
7
- import { Trigger } from '@dxos/async';
8
- import { live } from '@dxos/client/echo';
9
- import { TestBuilder } from '@dxos/client/testing';
10
-
11
- import { initFunctionsPlugin } from './plugin-init';
12
- import { setTestCallHandler } from './test/handler';
13
- import { createInitializedClients, inviteMember, startFunctionsHost, TestType } from '../testing';
14
- import { FunctionDef, FunctionTrigger, TriggerKind } from '../types';
15
-
16
- // TODO(wittjosiah): Doesn't work in vitest.
17
- describe.skip('functions e2e', () => {
18
- let testBuilder: TestBuilder;
19
-
20
- beforeAll(async () => {
21
- testBuilder = new TestBuilder();
22
- });
23
-
24
- afterAll(async () => {
25
- await testBuilder.destroy();
26
- });
27
-
28
- test('a function gets triggered in response to another peer object creations', async () => {
29
- // TODO(burdon): Create builder pattern.
30
- const functionRuntime = await startFunctionsHost(testBuilder, initFunctionsPlugin);
31
-
32
- const app = (await createInitializedClients(testBuilder, 1))[0];
33
- const space = await app.spaces.create();
34
- await inviteMember(space, functionRuntime.client);
35
-
36
- const uri = 'example.com/function/test';
37
- space.db.add(live(FunctionDef, { uri, route: '/test', handler: 'test' }));
38
- const triggerMeta: FunctionTrigger['meta'] = { name: 'DXOS' };
39
- space.db.add(
40
- live(FunctionTrigger, {
41
- function: uri,
42
- enabled: true,
43
- meta: triggerMeta,
44
- spec: {
45
- type: TriggerKind.Subscription,
46
- filter: { type: TestType.typename },
47
- },
48
- }),
49
- );
50
-
51
- const called = new Trigger<any>();
52
- setTestCallHandler(async (args) => {
53
- called.wake(args.event.data);
54
- return args.response.status(200);
55
- });
56
-
57
- await functionRuntime.waitForActiveTriggers(space);
58
- const addedObject = space.db.add(live(TestType, { title: '42' }));
59
-
60
- const callArgs = await called.wait();
61
- expect(callArgs.meta).to.deep.eq(triggerMeta);
62
- expect(callArgs.objects).to.deep.eq([addedObject.id]);
63
- expect(callArgs.spaceKey).to.eq(space.key.toHex());
64
- });
65
- });
@@ -1,8 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- export * from './setup';
6
- export * from './types';
7
- export * from './util';
8
- export * from './manifest';
@@ -1,15 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import type { FunctionManifest } from '../types';
6
-
7
- export const testFunctionManifest: FunctionManifest = {
8
- functions: [
9
- {
10
- uri: 'example.com/function/test',
11
- route: 'test',
12
- handler: 'test',
13
- },
14
- ],
15
- };
@@ -1,20 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { FunctionsPlugin } from '@dxos/agent';
6
- import { type Client } from '@dxos/client';
7
-
8
- import { type FunctionsPluginInitializer } from './setup';
9
-
10
- /**
11
- * Deliberately in a non-exported file to keep @dxos/agent as a devDependency.
12
- */
13
- export const initFunctionsPlugin: FunctionsPluginInitializer = async (client: Client) => {
14
- const plugin = new FunctionsPlugin();
15
- await plugin.initialize({ client, clientServices: client.services });
16
- await plugin.open();
17
- return {
18
- close: () => plugin.close(),
19
- };
20
- };
@@ -1,109 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { getRandomPort } from 'get-port-please';
6
- import path from 'node:path';
7
-
8
- import { waitForCondition } from '@dxos/async';
9
- import { Client, Config } from '@dxos/client';
10
- import { type Space } from '@dxos/client/echo';
11
- import { type TestBuilder } from '@dxos/client/testing';
12
- import { range } from '@dxos/util';
13
-
14
- import { TestType } from './types';
15
- import { FunctionRegistry } from '../function';
16
- import { DevServer, type DevServerOptions, Scheduler } from '../runtime';
17
- import { TriggerRegistry } from '../trigger';
18
- import { FunctionDef, FunctionTrigger } from '../types';
19
-
20
- export type FunctionsPluginInitializer = (client: Client) => Promise<{ close: () => Promise<void> }>;
21
-
22
- // TODO(burdon): Extend/wrap TestBuilder.
23
-
24
- export const createInitializedClients = async (testBuilder: TestBuilder, count: number = 1, config?: Config) => {
25
- const clients = range(count).map(
26
- () =>
27
- new Client({
28
- config,
29
- services: testBuilder.createLocalClientServices(),
30
- types: [FunctionDef, FunctionTrigger, TestType],
31
- }),
32
- );
33
-
34
- testBuilder.ctx.onDispose(() => Promise.all(clients.map((client) => client.destroy())));
35
- return Promise.all(
36
- clients.map(async (client, index) => {
37
- await client.initialize();
38
- await client.halo.createIdentity({ displayName: `Peer ${index}` });
39
- await client.spaces.waitUntilReady();
40
- return client;
41
- }),
42
- );
43
- };
44
-
45
- export const createFunctionRuntime = async (
46
- testBuilder: TestBuilder,
47
- pluginInitializer: FunctionsPluginInitializer,
48
- ): Promise<Client> => {
49
- const functionsPort = await getRandomPort('127.0.0.1');
50
- const config = new Config({
51
- runtime: {
52
- agent: {
53
- plugins: [{ id: 'dxos.org/agent/plugin/functions', config: { port: functionsPort } }],
54
- },
55
- },
56
- });
57
-
58
- const [client] = await createInitializedClients(testBuilder, 1, config);
59
- const plugin = await pluginInitializer(client);
60
- testBuilder.ctx.onDispose(() => plugin.close());
61
- return client;
62
- };
63
-
64
- export const startFunctionsHost = async (
65
- testBuilder: TestBuilder,
66
- pluginInitializer: FunctionsPluginInitializer,
67
- options?: DevServerOptions,
68
- ) => {
69
- const functionRuntime = await createFunctionRuntime(testBuilder, pluginInitializer);
70
- const functionsRegistry = new FunctionRegistry(functionRuntime);
71
- const devServer = await startDevServer(testBuilder, functionRuntime, functionsRegistry, options);
72
- const scheduler = await startScheduler(testBuilder, functionRuntime, devServer, functionsRegistry);
73
- return {
74
- scheduler,
75
- client: functionRuntime,
76
- waitForActiveTriggers: async (space: Space) => {
77
- await waitForCondition({ condition: () => scheduler.triggers.getActiveTriggers(space).length > 0 });
78
- },
79
- };
80
- };
81
-
82
- const startScheduler = async (
83
- testBuilder: TestBuilder,
84
- client: Client,
85
- devServer: DevServer,
86
- functionRegistry: FunctionRegistry,
87
- ) => {
88
- const triggerRegistry = new TriggerRegistry(client);
89
- const scheduler = new Scheduler(functionRegistry, triggerRegistry, { endpoint: devServer.endpoint });
90
- await scheduler.start();
91
- testBuilder.ctx.onDispose(() => scheduler.stop());
92
- return scheduler;
93
- };
94
-
95
- const startDevServer = async (
96
- testBuilder: TestBuilder,
97
- client: Client,
98
- functionRegistry: FunctionRegistry,
99
- options?: { baseDir?: string },
100
- ) => {
101
- const server = new DevServer(client, functionRegistry, {
102
- baseDir: path.join(__dirname, '../testing'),
103
- port: await getRandomPort('127.0.0.1'),
104
- ...options,
105
- });
106
- await server.start();
107
- testBuilder.ctx.onDispose(() => server.stop());
108
- return server;
109
- };
@@ -1,15 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import { type FunctionHandler } from '../../handler';
6
-
7
- let callHandler: FunctionHandler<any> = async ({ response }) => response.status(200);
8
-
9
- export const setTestCallHandler = (handler: FunctionHandler<any>) => {
10
- callHandler = handler;
11
- };
12
-
13
- export const handler: FunctionHandler<any> = async (args) => {
14
- return callHandler(args);
15
- };
@@ -1,7 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import { handler } from './handler';
6
-
7
- export default handler;
@@ -1,9 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { S, TypedObject } from '@dxos/echo-schema';
6
-
7
- export class TestType extends TypedObject({ typename: 'example.com/type/Test', version: '0.1.0' })({
8
- title: S.String,
9
- }) {}
@@ -1,26 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import type { Client } from '@dxos/client';
6
- import { Filter, type Space } from '@dxos/client/echo';
7
- import { performInvitation } from '@dxos/client/testing';
8
- import { invariant } from '@dxos/invariant';
9
- import { Invitation } from '@dxos/protocols/proto/dxos/client/services';
10
-
11
- import { FunctionTrigger } from '../types';
12
-
13
- export const triggerWebhook = async (space: Space, uri: string) => {
14
- const trigger = (
15
- await space.db.query(Filter.schema(FunctionTrigger, (trigger: FunctionTrigger) => trigger.function === uri)).run()
16
- ).objects[0];
17
- invariant(trigger.spec?.type === 'webhook');
18
- void fetch(`http://localhost:${trigger.spec.port}`);
19
- };
20
-
21
- export const inviteMember = async (host: Space, guest: Client) => {
22
- const [{ invitation: hostInvitation }] = await Promise.all(performInvitation({ host, guest: guest.spaces }));
23
- if (hostInvitation?.state !== Invitation.State.SUCCESS) {
24
- throw new Error(`Expected ${hostInvitation?.state} to be ${Invitation.State.SUCCESS}.`);
25
- }
26
- };
@@ -1,6 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- export * from './trigger-registry';
6
- export * from './type';
@@ -1,278 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import { afterEach, beforeEach, describe, expect, test } from 'vitest';
6
-
7
- import { sleep, Trigger, waitForCondition } from '@dxos/async';
8
- import { type Client } from '@dxos/client';
9
- import { type Space } from '@dxos/client/echo';
10
- import { TestBuilder } from '@dxos/client/testing';
11
- import { Context } from '@dxos/context';
12
- import { Filter } from '@dxos/echo-db';
13
- import { splitMeta } from '@dxos/echo-schema';
14
- import { live } from '@dxos/live-object';
15
- import { range } from '@dxos/util';
16
-
17
- import { TriggerRegistry } from './trigger-registry';
18
- import { createInitializedClients, TestType, triggerWebhook } from '../testing';
19
- import { type FunctionManifest, FunctionTrigger, TriggerKind } from '../types';
20
-
21
- const manifest: FunctionManifest = {
22
- triggers: [
23
- {
24
- '@meta': {
25
- keys: [
26
- {
27
- source: 'example.com',
28
- id: 'trigger-1',
29
- },
30
- ],
31
- },
32
- function: 'example.com/function/webhook-test',
33
- enabled: true,
34
- spec: {
35
- type: TriggerKind.Webhook,
36
- method: 'GET',
37
- },
38
- },
39
- {
40
- '@meta': {
41
- keys: [
42
- {
43
- source: 'example.com',
44
- id: 'trigger-2',
45
- },
46
- ],
47
- },
48
- function: 'example.com/function/subscription-test',
49
- enabled: true,
50
- spec: {
51
- type: TriggerKind.Subscription,
52
- filter: {
53
- type: TestType.typename,
54
- },
55
- },
56
- },
57
- ],
58
- };
59
-
60
- describe('trigger registry', () => {
61
- let ctx: Context;
62
- let testBuilder: TestBuilder;
63
-
64
- beforeEach(async () => {
65
- ctx = new Context();
66
- testBuilder = new TestBuilder();
67
- });
68
-
69
- afterEach(async () => {
70
- await ctx.dispose();
71
- await testBuilder.destroy();
72
- });
73
-
74
- describe('register', () => {
75
- test('creates new triggers', async () => {
76
- const [client] = await createInitializedClients(testBuilder);
77
- const registry = createRegistry(client);
78
- const space = await client.spaces.create();
79
- await registry.register(space, manifest);
80
- const { objects } = await space.db.query(Filter.schema(FunctionTrigger)).run();
81
- expect(objects.length).to.eq(manifest.triggers?.length);
82
-
83
- const expected = manifest.triggers?.map((trigger) => trigger.function).sort();
84
- expect(objects.map((object: FunctionTrigger) => object.function).sort()).to.deep.eq(expected);
85
- });
86
-
87
- test('set meta', () => {
88
- const trigger = live(FunctionTrigger, {
89
- function: 'example.com/function/webhook-test',
90
- spec: {
91
- type: TriggerKind.Webhook,
92
- method: 'GET',
93
- },
94
- });
95
-
96
- (trigger.meta ??= {}).test = 100;
97
- expect(trigger.meta.test).to.eq(100);
98
- });
99
- });
100
-
101
- // TODO(burdon): Server-only.
102
- describe.skip('activate', () => {
103
- test('invokes the provided callback', async () => {
104
- const [client] = await createInitializedClients(testBuilder);
105
- const space = await client.spaces.create();
106
- const registry = createRegistry(client);
107
- await registry.register(space, manifest);
108
- await registry.open(ctx);
109
- await waitForInactiveTriggers(registry, space);
110
-
111
- const callbackInvoked = new Trigger();
112
- const { objects: allTriggers } = await space.db.query(Filter.schema(FunctionTrigger)).run();
113
- const webhookTrigger = allTriggers.find((trigger: FunctionTrigger) => trigger.spec?.type === 'webhook')!;
114
- await registry.activate(space, webhookTrigger, async () => {
115
- callbackInvoked.wake();
116
- return 200;
117
- });
118
-
119
- setTimeout(() => triggerWebhook(space, webhookTrigger.function!));
120
- await callbackInvoked.wait();
121
- });
122
-
123
- test('removes from inactive list', async () => {
124
- const [client] = await createInitializedClients(testBuilder);
125
- const space = await client.spaces.create();
126
- const registry = createRegistry(client);
127
- await registry.register(space, manifest);
128
- await registry.open(ctx);
129
- await waitForInactiveTriggers(registry, space);
130
-
131
- const inactiveTrigger = registry.getInactiveTriggers(space)[0];
132
- await registry.activate(space, inactiveTrigger, async () => 200);
133
-
134
- const updatedInactiveList = registry.getInactiveTriggers(space);
135
- expect(updatedInactiveList.find((trigger: FunctionTrigger) => trigger.function === inactiveTrigger.function)).to
136
- .be.undefined;
137
- });
138
-
139
- // TODO(burdon): Test enable/disable trigger.
140
- });
141
-
142
- describe('deactivate', () => {
143
- test('trigger object deletion deactivates a trigger', async () => {
144
- const [client] = await createInitializedClients(testBuilder);
145
- const space = await client.spaces.create();
146
- const registry = createRegistry(client);
147
- await registry.register(space, manifest);
148
- await registry.open(ctx);
149
- await waitForInactiveTriggers(registry, space);
150
-
151
- const { objects: allTriggers } = await space.db.query(Filter.schema(FunctionTrigger)).run();
152
- const echoTrigger = allTriggers.find((trigger: FunctionTrigger) => trigger.spec?.type === 'subscription')!;
153
- let count = 0;
154
- await registry.activate(space, echoTrigger, async () => {
155
- count++;
156
- return 200;
157
- });
158
-
159
- space.db.add(live(TestType, { title: '1' }));
160
- await sleep(110);
161
- expect(count).to.eq(1);
162
-
163
- space.db.remove(echoTrigger);
164
- await sleep(110);
165
- space.db.add(live(TestType, { title: '2' }));
166
- await sleep(20);
167
- expect(count).to.eq(1);
168
- });
169
-
170
- test('registry closing deactivates a trigger', async () => {
171
- const [client] = await createInitializedClients(testBuilder);
172
- const space = await client.spaces.create();
173
- const registry = createRegistry(client);
174
- await registry.register(space, manifest);
175
- await registry.open(ctx);
176
- await waitForInactiveTriggers(registry, space);
177
-
178
- const { objects: allTriggers } = await space.db.query(Filter.schema(FunctionTrigger)).run();
179
- const echoTrigger = allTriggers.find((trigger: FunctionTrigger) => trigger.spec?.type === 'subscription')!;
180
- let count = 0;
181
- await registry.activate(space, echoTrigger, async () => {
182
- count++;
183
- return 200;
184
- });
185
-
186
- await registry.close();
187
-
188
- space.db.add(live(TestType, { title: '1' }));
189
- await sleep(20);
190
- expect(count).to.eq(0);
191
- });
192
- });
193
-
194
- describe('trigger events', () => {
195
- test('event fired when all registered are opened', async () => {
196
- const [client] = await createInitializedClients(testBuilder);
197
- const registry = createRegistry(client);
198
- await client.spaces.default.waitUntilReady();
199
- const triggers = createTriggers(client.spaces.default, 3);
200
-
201
- const triggersRegistered = new Trigger<FunctionTrigger[]>();
202
- registry.registered.on((fn) => {
203
- expect(fn.space.key.toHex()).to.eq(client.spaces.default.key.toHex());
204
- triggersRegistered.wake(fn.triggers);
205
- });
206
-
207
- void registry.open(ctx);
208
- const functions = await triggersRegistered.wait();
209
- const expected = triggers.map((object) => object.id).sort();
210
- expect(functions.map((fn) => fn.id).sort()).to.deep.eq(expected);
211
- });
212
-
213
- test('event fired when a new trigger is added', async () => {
214
- const [client] = await createInitializedClients(testBuilder);
215
- const registry = createRegistry(client);
216
- const space = await client.spaces.create();
217
- await space.waitUntilReady();
218
-
219
- const triggerRegistered = new Trigger<FunctionTrigger>();
220
- registry.registered.on((fn) => {
221
- expect(fn.triggers.length).to.eq(1);
222
- triggerRegistered.wake(fn.triggers[0]);
223
- });
224
-
225
- await registry.open(ctx);
226
- await registry.register(space, { triggers: manifest?.triggers?.slice(0, 1) });
227
- const registered = await triggerRegistered.wait();
228
- expect(registered.function).to.eq(manifest.triggers![0].function);
229
- });
230
-
231
- test('event fired when a new trigger is removed', async () => {
232
- const [client] = await createInitializedClients(testBuilder);
233
- const registry = createRegistry(client);
234
- const space = await client.spaces.create();
235
- await space.waitUntilReady();
236
- const triggers = createTriggers(space, 3);
237
-
238
- const triggerLoaded = new Trigger();
239
- registry.registered.on(() => {
240
- triggerLoaded.wake();
241
- });
242
-
243
- const triggerRemoved = new Trigger<FunctionTrigger>();
244
- registry.removed.on((fn) => {
245
- expect(fn.triggers.length).to.eq(1);
246
- triggerRemoved.wake(fn.triggers[0]);
247
- });
248
-
249
- await registry.register(space, manifest);
250
- await registry.open(ctx);
251
- await triggerLoaded.wait();
252
-
253
- space.db.remove(triggers[0]);
254
- const removedTrigger = await triggerRemoved.wait();
255
- expect(removedTrigger.id).to.eq(triggers[0].id);
256
- });
257
- });
258
-
259
- const createRegistry = (client: Client) => {
260
- const registry = new TriggerRegistry(client);
261
- ctx.onDispose(() => registry.close());
262
- return registry;
263
- };
264
-
265
- const createTriggers = (space: Space, count: number) => {
266
- const triggers = range(count, () => {
267
- const { meta, object } = splitMeta(manifest.triggers![0]);
268
- return live(FunctionTrigger, object, meta);
269
- });
270
-
271
- triggers.forEach((trigger) => space.db.add(trigger));
272
- return triggers;
273
- };
274
-
275
- const waitForInactiveTriggers = async (registry: TriggerRegistry, space: Space) => {
276
- await waitForCondition({ condition: () => registry.getInactiveTriggers(space).length > 0 });
277
- };
278
- });