@dxos/functions 0.8.4-main.a4bbb77 → 0.8.4-main.ae835ea

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 (142) hide show
  1. package/dist/lib/browser/bundler/index.mjs +16 -25
  2. package/dist/lib/browser/bundler/index.mjs.map +3 -3
  3. package/dist/lib/browser/chunk-M6EXIREF.mjs +610 -0
  4. package/dist/lib/browser/chunk-M6EXIREF.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +957 -977
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/testing/index.mjs +8 -6
  9. package/dist/lib/browser/testing/index.mjs.map +3 -3
  10. package/dist/lib/node-esm/bundler/index.mjs +16 -25
  11. package/dist/lib/node-esm/bundler/index.mjs.map +3 -3
  12. package/dist/lib/node-esm/chunk-P3IATZMZ.mjs +612 -0
  13. package/dist/lib/node-esm/chunk-P3IATZMZ.mjs.map +7 -0
  14. package/dist/lib/node-esm/index.mjs +957 -977
  15. package/dist/lib/node-esm/index.mjs.map +4 -4
  16. package/dist/lib/node-esm/meta.json +1 -1
  17. package/dist/lib/node-esm/testing/index.mjs +8 -6
  18. package/dist/lib/node-esm/testing/index.mjs.map +3 -3
  19. package/dist/types/src/bundler/bundler.d.ts.map +1 -1
  20. package/dist/types/src/e2e/deploy.test.d.ts +2 -0
  21. package/dist/types/src/e2e/deploy.test.d.ts.map +1 -0
  22. package/dist/types/src/example/fib.d.ts.map +1 -0
  23. package/dist/types/src/example/forex-effect.d.ts +3 -0
  24. package/dist/types/src/example/forex-effect.d.ts.map +1 -0
  25. package/dist/types/src/example/index.d.ts +12 -0
  26. package/dist/types/src/example/index.d.ts.map +1 -0
  27. package/dist/types/src/example/reply.d.ts.map +1 -0
  28. package/dist/types/src/example/sleep.d.ts.map +1 -0
  29. package/dist/types/src/executor/executor.d.ts.map +1 -1
  30. package/dist/types/src/handler.d.ts +20 -24
  31. package/dist/types/src/handler.d.ts.map +1 -1
  32. package/dist/types/src/index.d.ts +4 -5
  33. package/dist/types/src/index.d.ts.map +1 -1
  34. package/dist/types/src/services/credentials.d.ts +6 -2
  35. package/dist/types/src/services/credentials.d.ts.map +1 -1
  36. package/dist/types/src/services/database.d.ts +6 -2
  37. package/dist/types/src/services/database.d.ts.map +1 -1
  38. package/dist/types/src/services/event-logger.d.ts +4 -1
  39. package/dist/types/src/services/event-logger.d.ts.map +1 -1
  40. package/dist/types/src/services/function-invocation-service.d.ts +5 -3
  41. package/dist/types/src/services/function-invocation-service.d.ts.map +1 -1
  42. package/dist/types/src/services/local-function-execution.d.ts +5 -3
  43. package/dist/types/src/services/local-function-execution.d.ts.map +1 -1
  44. package/dist/types/src/services/queues.d.ts +3 -1
  45. package/dist/types/src/services/queues.d.ts.map +1 -1
  46. package/dist/types/src/services/remote-function-execution-service.d.ts +3 -1
  47. package/dist/types/src/services/remote-function-execution-service.d.ts.map +1 -1
  48. package/dist/types/src/services/service-container.d.ts +2 -1
  49. package/dist/types/src/services/service-container.d.ts.map +1 -1
  50. package/dist/types/src/services/service-registry.d.ts +3 -1
  51. package/dist/types/src/services/service-registry.d.ts.map +1 -1
  52. package/dist/types/src/services/tracing.d.ts +4 -2
  53. package/dist/types/src/services/tracing.d.ts.map +1 -1
  54. package/dist/types/src/testing/layer.d.ts +3 -2
  55. package/dist/types/src/testing/layer.d.ts.map +1 -1
  56. package/dist/types/src/testing/logger.d.ts +1 -1
  57. package/dist/types/src/testing/logger.d.ts.map +1 -1
  58. package/dist/types/src/testing/services.d.ts +1 -1
  59. package/dist/types/src/testing/services.d.ts.map +1 -1
  60. package/dist/types/src/trace.d.ts +4 -4
  61. package/dist/types/src/trace.d.ts.map +1 -1
  62. package/dist/types/src/translations.d.ts +2 -2
  63. package/dist/types/src/translations.d.ts.map +1 -1
  64. package/dist/types/src/triggers/input-builder.d.ts +2 -2
  65. package/dist/types/src/triggers/input-builder.d.ts.map +1 -1
  66. package/dist/types/src/triggers/invocation-tracer.d.ts +5 -3
  67. package/dist/types/src/triggers/invocation-tracer.d.ts.map +1 -1
  68. package/dist/types/src/triggers/trigger-dispatcher.d.ts +10 -6
  69. package/dist/types/src/triggers/trigger-dispatcher.d.ts.map +1 -1
  70. package/dist/types/src/triggers/trigger-state-store.d.ts +5 -4
  71. package/dist/types/src/triggers/trigger-state-store.d.ts.map +1 -1
  72. package/dist/types/src/types/Function.d.ts +47 -0
  73. package/dist/types/src/types/Function.d.ts.map +1 -0
  74. package/dist/types/src/types/Script.d.ts +28 -0
  75. package/dist/types/src/types/Script.d.ts.map +1 -0
  76. package/dist/types/src/types/Trigger.d.ts +139 -0
  77. package/dist/types/src/types/Trigger.d.ts.map +1 -0
  78. package/dist/types/src/types/TriggerEvent.d.ts +44 -0
  79. package/dist/types/src/types/TriggerEvent.d.ts.map +1 -0
  80. package/dist/types/src/types/index.d.ts +5 -0
  81. package/dist/types/src/types/index.d.ts.map +1 -0
  82. package/dist/types/src/url.d.ts +1 -1
  83. package/dist/types/src/url.d.ts.map +1 -1
  84. package/dist/types/tsconfig.tsbuildinfo +1 -1
  85. package/package.json +24 -36
  86. package/src/bundler/bundler.ts +7 -3
  87. package/src/e2e/deploy.test.ts +69 -0
  88. package/src/{examples → example}/fib.ts +2 -1
  89. package/src/example/forex-effect.ts +40 -0
  90. package/src/example/index.ts +13 -0
  91. package/src/{examples → example}/reply.ts +3 -1
  92. package/src/{examples → example}/sleep.ts +2 -1
  93. package/src/executor/executor.ts +2 -1
  94. package/src/handler.ts +23 -19
  95. package/src/index.ts +4 -5
  96. package/src/services/credentials.ts +7 -2
  97. package/src/services/database.ts +6 -2
  98. package/src/services/event-logger.ts +4 -1
  99. package/src/services/function-invocation-service.test.ts +3 -1
  100. package/src/services/function-invocation-service.ts +5 -3
  101. package/src/services/local-function-execution.ts +10 -7
  102. package/src/services/queues.ts +3 -1
  103. package/src/services/remote-function-execution-service.ts +3 -1
  104. package/src/services/service-container.ts +2 -1
  105. package/src/services/service-registry.test.ts +4 -1
  106. package/src/services/service-registry.ts +7 -3
  107. package/src/services/tracing.ts +4 -2
  108. package/src/testing/layer.ts +6 -4
  109. package/src/testing/logger.ts +2 -1
  110. package/src/testing/persist-database.test.ts +1 -1
  111. package/src/testing/services.ts +1 -1
  112. package/src/trace.ts +5 -5
  113. package/src/translations.ts +2 -2
  114. package/src/triggers/input-builder.ts +2 -2
  115. package/src/triggers/invocation-tracer.ts +5 -3
  116. package/src/triggers/trigger-dispatcher.test.ts +57 -44
  117. package/src/triggers/trigger-dispatcher.ts +26 -27
  118. package/src/triggers/trigger-state-store.ts +6 -5
  119. package/src/{schema.ts → types/Function.ts} +9 -26
  120. package/src/types/Script.ts +33 -0
  121. package/src/types/Trigger.ts +139 -0
  122. package/src/types/TriggerEvent.ts +62 -0
  123. package/src/types/index.ts +8 -0
  124. package/src/url.ts +1 -1
  125. package/dist/lib/browser/chunk-C2Z7LCJ2.mjs +0 -649
  126. package/dist/lib/browser/chunk-C2Z7LCJ2.mjs.map +0 -7
  127. package/dist/lib/node-esm/chunk-AH3AZM2U.mjs +0 -651
  128. package/dist/lib/node-esm/chunk-AH3AZM2U.mjs.map +0 -7
  129. package/dist/types/src/examples/fib.d.ts.map +0 -1
  130. package/dist/types/src/examples/index.d.ts +0 -4
  131. package/dist/types/src/examples/index.d.ts.map +0 -1
  132. package/dist/types/src/examples/reply.d.ts.map +0 -1
  133. package/dist/types/src/examples/sleep.d.ts.map +0 -1
  134. package/dist/types/src/schema.d.ts +0 -43
  135. package/dist/types/src/schema.d.ts.map +0 -1
  136. package/dist/types/src/types.d.ts +0 -221
  137. package/dist/types/src/types.d.ts.map +0 -1
  138. package/src/examples/index.ts +0 -7
  139. package/src/types.ts +0 -214
  140. /package/dist/types/src/{examples → example}/fib.d.ts +0 -0
  141. /package/dist/types/src/{examples → example}/reply.d.ts +0 -0
  142. /package/dist/types/src/{examples → example}/sleep.d.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/functions",
3
- "version": "0.8.4-main.a4bbb77",
3
+ "version": "0.8.4-main.ae835ea",
4
4
  "description": "Functions API and runtime.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -52,45 +52,33 @@
52
52
  ],
53
53
  "dependencies": {
54
54
  "@effect/platform": "0.92.1",
55
- "@preact/signals-core": "^1.12.1",
56
- "cron": "^3.1.6",
57
- "cron-schedule": "^5.0.4",
58
55
  "effect": "3.18.3",
59
56
  "esbuild-wasm": "^0.16.14",
60
- "express": "^4.19.2",
61
- "get-port-please": "^3.1.1",
62
57
  "i18next": "^24.2.1",
63
58
  "iso-did": "^1.6.0",
64
- "ws": "^8.14.2",
65
- "@dxos/ai": "0.8.4-main.a4bbb77",
66
- "@dxos/async": "0.8.4-main.a4bbb77",
67
- "@dxos/client": "0.8.4-main.a4bbb77",
68
- "@dxos/client-protocol": "0.8.4-main.a4bbb77",
69
- "@dxos/context": "0.8.4-main.a4bbb77",
70
- "@dxos/debug": "0.8.4-main.a4bbb77",
71
- "@dxos/crypto": "0.8.4-main.a4bbb77",
72
- "@dxos/echo-db": "0.8.4-main.a4bbb77",
73
- "@dxos/echo": "0.8.4-main.a4bbb77",
74
- "@dxos/echo-pipeline": "0.8.4-main.a4bbb77",
75
- "@dxos/echo-protocol": "0.8.4-main.a4bbb77",
76
- "@dxos/echo-schema": "0.8.4-main.a4bbb77",
77
- "@dxos/edge-client": "0.8.4-main.a4bbb77",
78
- "@dxos/effect": "0.8.4-main.a4bbb77",
79
- "@dxos/errors": "0.8.4-main.a4bbb77",
80
- "@dxos/invariant": "0.8.4-main.a4bbb77",
81
- "@dxos/keys": "0.8.4-main.a4bbb77",
82
- "@dxos/kv-store": "0.8.4-main.a4bbb77",
83
- "@dxos/live-object": "0.8.4-main.a4bbb77",
84
- "@dxos/log": "0.8.4-main.a4bbb77",
85
- "@dxos/node-std": "0.8.4-main.a4bbb77",
86
- "@dxos/protocols": "0.8.4-main.a4bbb77",
87
- "@dxos/schema": "0.8.4-main.a4bbb77",
88
- "@dxos/util": "0.8.4-main.a4bbb77"
89
- },
90
- "devDependencies": {
91
- "@types/express": "^4.17.17",
92
- "@types/ws": "^7.4.0",
93
- "@dxos/agent": "0.8.4-main.a4bbb77"
59
+ "@dxos/ai": "0.8.4-main.ae835ea",
60
+ "@dxos/async": "0.8.4-main.ae835ea",
61
+ "@dxos/client": "0.8.4-main.ae835ea",
62
+ "@dxos/client-protocol": "0.8.4-main.ae835ea",
63
+ "@dxos/context": "0.8.4-main.ae835ea",
64
+ "@dxos/crypto": "0.8.4-main.ae835ea",
65
+ "@dxos/echo-db": "0.8.4-main.ae835ea",
66
+ "@dxos/debug": "0.8.4-main.ae835ea",
67
+ "@dxos/echo": "0.8.4-main.ae835ea",
68
+ "@dxos/echo-pipeline": "0.8.4-main.ae835ea",
69
+ "@dxos/echo-protocol": "0.8.4-main.ae835ea",
70
+ "@dxos/edge-client": "0.8.4-main.ae835ea",
71
+ "@dxos/effect": "0.8.4-main.ae835ea",
72
+ "@dxos/errors": "0.8.4-main.ae835ea",
73
+ "@dxos/invariant": "0.8.4-main.ae835ea",
74
+ "@dxos/kv-store": "0.8.4-main.ae835ea",
75
+ "@dxos/live-object": "0.8.4-main.ae835ea",
76
+ "@dxos/log": "0.8.4-main.ae835ea",
77
+ "@dxos/node-std": "0.8.4-main.ae835ea",
78
+ "@dxos/schema": "0.8.4-main.ae835ea",
79
+ "@dxos/protocols": "0.8.4-main.ae835ea",
80
+ "@dxos/util": "0.8.4-main.ae835ea",
81
+ "@dxos/keys": "0.8.4-main.ae835ea"
94
82
  },
95
83
  "publishConfig": {
96
84
  "access": "public"
@@ -2,8 +2,12 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { FetchHttpClient, HttpClient } from '@effect/platform';
6
- import { Duration, Effect, Schedule, pipe } from 'effect';
5
+ import * as FetchHttpClient from '@effect/platform/FetchHttpClient';
6
+ import * as HttpClient from '@effect/platform/HttpClient';
7
+ import * as Duration from 'effect/Duration';
8
+ import * as Effect from 'effect/Effect';
9
+ import * as Function from 'effect/Function';
10
+ import * as Schedule from 'effect/Schedule';
7
11
  import { type BuildOptions, type BuildResult, type Loader, type Plugin, build, initialize } from 'esbuild-wasm';
8
12
 
9
13
  import { subtleCrypto } from '@dxos/crypto';
@@ -277,7 +281,7 @@ const httpPlugin: Plugin = {
277
281
  return { contents: text, loader: 'jsx' as Loader };
278
282
  }).pipe(
279
283
  Effect.retry(
280
- pipe(
284
+ Function.pipe(
281
285
  Schedule.exponential(Duration.millis(INITIAL_DELAY)),
282
286
  Schedule.jittered,
283
287
  Schedule.intersect(Schedule.recurs(MAX_RETRIES - 1)),
@@ -0,0 +1,69 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { readFile } from 'node:fs/promises';
6
+
7
+ import { describe, expect, test } from 'vitest';
8
+
9
+ import { Client, Config } from '@dxos/client';
10
+ import { createEdgeIdentity } from '@dxos/client/edge';
11
+ import { Bundler } from '@dxos/functions/bundler';
12
+ import { uploadWorkerFunction } from '@dxos/functions/edge';
13
+ import { invariant } from '@dxos/invariant';
14
+ import { log } from '@dxos/log';
15
+
16
+ describe.runIf(process.env.DX_TEST_TAGS?.includes('functions-e2e'))('Functions deployment', () => {
17
+ test('deploys FOREX (effect) function and invokes it via EDGE (main)', { timeout: 120_000 }, async () => {
18
+ const config = new Config({
19
+ version: 1,
20
+ runtime: {
21
+ services: {
22
+ edge: { url: 'https://edge-main.dxos.workers.dev' },
23
+ },
24
+ },
25
+ });
26
+
27
+ const client = new Client({ config });
28
+ await client.initialize();
29
+ await client.halo.createIdentity();
30
+
31
+ const space = await client.spaces.create();
32
+ await space.waitUntilReady();
33
+
34
+ // Inline echo function source.
35
+ const source = await readFile(new URL('../examples/forex-effect.ts', import.meta.url), 'utf-8');
36
+
37
+ // Bundle and upload.
38
+ const bundler = new Bundler({ platform: 'node', sandboxedModules: [], remoteModules: {} });
39
+ const buildResult = await bundler.bundle({ source });
40
+ if ('error' in buildResult) {
41
+ throw buildResult.error ?? new Error('Bundle creation failed');
42
+ }
43
+
44
+ const { functionId } = await uploadWorkerFunction({
45
+ client,
46
+ ownerPublicKey: space.key,
47
+ version: '0.0.1',
48
+ entryPoint: buildResult.entryPoint,
49
+ assets: { [buildResult.entryPoint]: buildResult.asset },
50
+ name: 'e2e-echo',
51
+ });
52
+
53
+ expect(functionId).toBeDefined();
54
+
55
+ // Invoke deployed function via EDGE directly.
56
+ const edgeClient = client.edge;
57
+ invariant(edgeClient, 'edgeClient is required');
58
+ edgeClient.setIdentity(createEdgeIdentity(client));
59
+
60
+ const input = { from: 'USD', to: 'EUR' };
61
+ const result = await edgeClient.invokeFunction({ functionId }, input);
62
+ log.info('>>> result', { result, functionId });
63
+ const resultNumber = Number(result);
64
+ expect(resultNumber).toBeGreaterThan(0);
65
+ expect(resultNumber).toBeLessThan(100);
66
+
67
+ await client.destroy();
68
+ });
69
+ });
@@ -2,7 +2,8 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Effect, Schema } from 'effect';
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Schema from 'effect/Schema';
6
7
 
7
8
  import { defineFunction } from '../handler';
8
9
 
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ // @ts-ignore
6
+ import { S, defineFunction } from 'dxos:functions';
7
+ import {
8
+ FetchHttpClient,
9
+ HttpClient,
10
+ HttpClientRequest,
11
+ // @ts-ignore
12
+ } from 'https://esm.sh/@effect/platform@0.89.0?deps=effect@3.17.0&bundle=false';
13
+ // @ts-ignore
14
+ import { Effect, Schedule } from 'https://esm.sh/effect@3.17.0?bundle=false';
15
+
16
+ export default defineFunction({
17
+ key: 'dxos.org/script/forex-effect',
18
+ name: 'Forex Effect',
19
+ description: 'Returns the exchange rate between two currencies.',
20
+
21
+ inputSchema: S.Struct({
22
+ from: S.String.annotations({ description: 'The source currency' }),
23
+ to: S.String.annotations({ description: 'The target currency' }),
24
+ }),
25
+
26
+ outputSchema: S.String.annotations({ description: 'The exchange rate between the two currencies' }),
27
+
28
+ handler: async ({ data: { from, to } }: any) =>
29
+ Effect.gen(function* () {
30
+ const res = yield* HttpClientRequest.get(`https://free.ratesdb.com/v1/rates?from=${from}&to=${to}`).pipe(
31
+ HttpClient.execute,
32
+ Effect.flatMap((res: any) => res.json),
33
+ Effect.timeout('1 second'),
34
+ Effect.retry(Schedule.exponential(1_000).pipe(Schedule.compose(Schedule.recurs(3)))),
35
+ Effect.scoped,
36
+ );
37
+
38
+ return res.data.rates[to].toString();
39
+ }).pipe(Effect.provide(FetchHttpClient.layer)),
40
+ });
@@ -0,0 +1,13 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { default as fib$ } from './fib';
6
+ import { default as reply$ } from './reply';
7
+ import { default as sleep$ } from './sleep';
8
+
9
+ export namespace Example {
10
+ export const fib = fib$;
11
+ export const reply = reply$;
12
+ export const sleep = sleep$;
13
+ }
@@ -2,7 +2,9 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Console, Effect, Schema } from 'effect';
5
+ import * as Console from 'effect/Console';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Schema from 'effect/Schema';
6
8
 
7
9
  import { defineFunction } from '../handler';
8
10
 
@@ -2,7 +2,8 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Effect, Schema } from 'effect';
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Schema from 'effect/Schema';
6
7
 
7
8
  import { defineFunction } from '../handler';
8
9
 
@@ -2,7 +2,8 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Effect, Schema } from 'effect';
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Schema from 'effect/Schema';
6
7
 
7
8
  import { type SpaceId } from '@dxos/client/echo';
8
9
  import { runAndForwardErrors } from '@dxos/effect';
package/src/handler.ts CHANGED
@@ -2,17 +2,19 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type Context, Effect, Schema, type Types } from 'effect';
5
+ import type * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Schema from 'effect/Schema';
6
8
 
7
9
  import { Obj, Type } from '@dxos/echo';
10
+ import { type HasId } from '@dxos/echo/internal';
8
11
  import { type EchoDatabase } from '@dxos/echo-db';
9
- import { type HasId } from '@dxos/echo-schema';
10
12
  import { assertArgument } from '@dxos/invariant';
11
13
  import { type DXN, type SpaceId } from '@dxos/keys';
12
14
  import { type QueryResult } from '@dxos/protocols';
13
15
 
14
- import { FunctionType } from './schema';
15
16
  import { type Services } from './services';
17
+ import { Function } from './types';
16
18
  import { getUserFunctionIdInMetadata, setUserFunctionIdInMetadata } from './url';
17
19
 
18
20
  // TODO(burdon): Model after http request. Ref Lambda/OpenFaaS.
@@ -104,23 +106,25 @@ export type FunctionDefinition<T = any, O = any> = {
104
106
  * deployedFunctionId:
105
107
  * - Backend deployment ID assigned by the EDGE function service (typically a UUID).
106
108
  * - Used for remote invocation via `FunctionInvocationService` → `RemoteFunctionExecutionService`.
107
- * - Persisted on the corresponding ECHO `FunctionType` object's metadata under the
109
+ * - Persisted on the corresponding ECHO `Function.Function` object's metadata under the
108
110
  * `FUNCTIONS_META_KEY` and retrieved with `getUserFunctionIdInMetadata`.
109
111
  */
110
112
  deployedFunctionId?: string;
111
113
  };
112
114
  };
113
115
 
116
+ export type FunctionProps<T, O> = {
117
+ key: string;
118
+ name: string;
119
+ description?: string;
120
+ inputSchema: Schema.Schema<T, any>;
121
+ outputSchema?: Schema.Schema<O, any>;
122
+ handler: FunctionHandler<T, O>;
123
+ };
124
+
114
125
  // TODO(dmaretskyi): Output type doesn't get typechecked.
115
126
  export const defineFunction: {
116
- <I, O>(params: {
117
- key: string;
118
- name: string;
119
- description?: string;
120
- inputSchema: Schema.Schema<I, any>;
121
- outputSchema?: Schema.Schema<O, any>;
122
- handler: Types.NoInfer<FunctionHandler<I, O>>;
123
- }): FunctionDefinition<I, O>;
127
+ <I, O>(params: FunctionProps<I, O>): FunctionDefinition<I, O>;
124
128
  } = ({ key, name, description, inputSchema, outputSchema = Schema.Any, handler }) => {
125
129
  if (!Schema.isSchema(inputSchema)) {
126
130
  throw new Error('Input schema must be a valid schema');
@@ -166,7 +170,7 @@ export const defineFunction: {
166
170
  inputSchema,
167
171
  outputSchema,
168
172
  handler: handlerWithSpan,
169
- };
173
+ } satisfies FunctionDefinition.Any;
170
174
  };
171
175
 
172
176
  export const FunctionDefinition = {
@@ -174,12 +178,12 @@ export const FunctionDefinition = {
174
178
  isFunction: (value: unknown): value is FunctionDefinition.Any => {
175
179
  return typeof value === 'object' && value !== null && Symbol.for('@dxos/functions/FunctionDefinition') in value;
176
180
  },
177
- serialize: (functionDef: FunctionDefinition.Any): FunctionType => {
181
+ serialize: (functionDef: FunctionDefinition.Any): Function.Function => {
178
182
  assertArgument(FunctionDefinition.isFunction(functionDef), 'functionDef');
179
183
  return serializeFunction(functionDef);
180
184
  },
181
- deserialize: (functionObj: FunctionType): FunctionDefinition.Any => {
182
- assertArgument(Obj.instanceOf(FunctionType, functionObj), 'functionObj');
185
+ deserialize: (functionObj: Function.Function): FunctionDefinition.Any => {
186
+ assertArgument(Obj.instanceOf(Function.Function, functionObj), 'functionObj');
183
187
  return deserializeFunction(functionObj);
184
188
  },
185
189
  };
@@ -189,8 +193,8 @@ export declare namespace FunctionDefinition {
189
193
  export type Output<T extends FunctionDefinition> = T extends FunctionDefinition<any, infer O> ? O : never;
190
194
  }
191
195
 
192
- export const serializeFunction = (functionDef: FunctionDefinition<any, any>): FunctionType => {
193
- const fn = Obj.make(FunctionType, {
196
+ export const serializeFunction = (functionDef: FunctionDefinition<any, any>): Function.Function => {
197
+ const fn = Function.make({
194
198
  key: functionDef.key,
195
199
  name: functionDef.name,
196
200
  version: '0.1.0',
@@ -204,7 +208,7 @@ export const serializeFunction = (functionDef: FunctionDefinition<any, any>): Fu
204
208
  return fn;
205
209
  };
206
210
 
207
- export const deserializeFunction = (functionObj: FunctionType): FunctionDefinition<unknown, unknown> => {
211
+ export const deserializeFunction = (functionObj: Function.Function): FunctionDefinition<unknown, unknown> => {
208
212
  return {
209
213
  [typeId]: true,
210
214
  // TODO(dmaretskyi): Fix key.
package/src/index.ts CHANGED
@@ -3,12 +3,11 @@
3
3
  //
4
4
 
5
5
  export * from './errors';
6
+ export * from './example';
7
+ export * from './executor';
6
8
  export * from './handler';
7
- export * from './schema';
9
+ export * from './services';
8
10
  export * from './trace';
11
+ export * from './triggers';
9
12
  export * from './types';
10
13
  export * from './url';
11
- export * from './triggers';
12
- export * from './services';
13
- export * from './executor';
14
- export * as exampleFunctions from './examples';
@@ -2,8 +2,13 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { HttpClient, HttpClientRequest } from '@effect/platform';
6
- import { type Config, Context, Effect, Layer, Redacted } from 'effect';
5
+ import * as HttpClient from '@effect/platform/HttpClient';
6
+ import * as HttpClientRequest from '@effect/platform/HttpClientRequest';
7
+ import type * as Config from 'effect/Config';
8
+ import * as Context from 'effect/Context';
9
+ import * as Effect from 'effect/Effect';
10
+ import * as Layer from 'effect/Layer';
11
+ import * as Redacted from 'effect/Redacted';
7
12
 
8
13
  import { Query } from '@dxos/echo';
9
14
  import { DataType } from '@dxos/schema';
@@ -2,7 +2,11 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Context, Effect, Layer, Option, type Schema } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+ import * as Option from 'effect/Option';
9
+ import type * as Schema from 'effect/Schema';
6
10
 
7
11
  import {
8
12
  type Filter,
@@ -14,9 +18,9 @@ import {
14
18
  type Relation,
15
19
  type Type,
16
20
  } from '@dxos/echo';
21
+ import type { EchoSchema } from '@dxos/echo/internal';
17
22
  import type { EchoDatabase, FlushOptions, OneShotQueryResult, QueryResult, SchemaRegistryQuery } from '@dxos/echo-db';
18
23
  import type { SchemaRegistryPreparedQuery } from '@dxos/echo-db';
19
- import type { EchoSchema } from '@dxos/echo-schema';
20
24
  import { promiseWithCauseCapture } from '@dxos/effect';
21
25
  import { invariant } from '@dxos/invariant';
22
26
  import type { DXN } from '@dxos/keys';
@@ -2,7 +2,10 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Context, Effect, Layer, Schema } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+ import * as Schema from 'effect/Schema';
6
9
 
7
10
  import { Obj, Type } from '@dxos/echo';
8
11
  import { invariant } from '@dxos/invariant';
@@ -3,7 +3,9 @@
3
3
  //
4
4
 
5
5
  import { describe, expect, it } from '@effect/vitest';
6
- import { Effect, Layer, Schema } from 'effect';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+ import * as Schema from 'effect/Schema';
7
9
 
8
10
  import { AiService } from '@dxos/ai';
9
11
 
@@ -1,7 +1,9 @@
1
1
  //
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
- import { Context, Effect, Layer } from 'effect';
4
+ import * as Context from 'effect/Context';
5
+ import * as Effect from 'effect/Effect';
6
+ import * as Layer from 'effect/Layer';
5
7
 
6
8
  import { AiService } from '@dxos/ai';
7
9
 
@@ -51,7 +53,7 @@ export class FunctionInvocationService extends Context.Tag('@dxos/functions/Func
51
53
  static layerTest = ({
52
54
  functions = [],
53
55
  }: {
54
- functions?: FunctionDefinition<any, any>[];
56
+ functions?: readonly FunctionDefinition<any, any>[];
55
57
  } = {}): Layer.Layer<
56
58
  FunctionInvocationService,
57
59
  never,
@@ -71,7 +73,7 @@ export class FunctionInvocationService extends Context.Tag('@dxos/functions/Func
71
73
  static layerTestMocked = ({
72
74
  functions,
73
75
  }: {
74
- functions: FunctionDefinition<any, any>[];
76
+ functions?: readonly FunctionDefinition<any, any>[];
75
77
  }): Layer.Layer<FunctionInvocationService> =>
76
78
  FunctionInvocationService.layerTest({ functions }).pipe(
77
79
  Layer.provide(AiService.notAvailable),
@@ -2,7 +2,10 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Context, Effect, Layer, Schema } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
8
+ import * as Schema from 'effect/Schema';
6
9
 
7
10
  import { AiService } from '@dxos/ai';
8
11
  import { todo } from '@dxos/debug';
@@ -16,7 +19,7 @@ import { DatabaseService } from './database';
16
19
  import { type ComputeEventLogger } from './event-logger';
17
20
  import { QueueService } from './queues';
18
21
  import { RemoteFunctionExecutionService } from './remote-function-execution-service';
19
- import type { Services } from './service-container';
22
+ import { type Services } from './service-container';
20
23
  import { type TracingService } from './tracing';
21
24
 
22
25
  /**
@@ -76,7 +79,7 @@ const invokeFunction = (
76
79
  input: any,
77
80
  ): Effect.Effect<unknown, never, Services> =>
78
81
  Effect.gen(function* () {
79
- // Assert input matches schema
82
+ // Assert input matches schema.
80
83
  try {
81
84
  const assertInput = functionDef.inputSchema.pipe(Schema.asserts);
82
85
  (assertInput as any)(input);
@@ -92,7 +95,7 @@ const invokeFunction = (
92
95
  },
93
96
  };
94
97
 
95
- log.info('Invoking function', { name: functionDef.name, input });
98
+ log.info('invoking function', { name: functionDef.name, input });
96
99
 
97
100
  // TODO(dmaretskyi): This should be delegated to a function invoker service.
98
101
  const data = yield* Effect.gen(function* () {
@@ -116,9 +119,9 @@ const invokeFunction = (
116
119
  ),
117
120
  );
118
121
 
119
- log.info('Function completed', { name: functionDef.name, input, data });
122
+ log.info('completed', { function: functionDef.name, input, data });
120
123
 
121
- // Assert output matches schema
124
+ // Assert output matches schema.
122
125
  try {
123
126
  const assertOutput = functionDef.outputSchema?.pipe(Schema.asserts);
124
127
  (assertOutput as any)(data);
@@ -137,7 +140,7 @@ export class FunctionImplementationResolver extends Context.Tag('@dxos/functions
137
140
  ): Effect.Effect<FunctionDefinition<I, O>, FunctionNotFoundError>;
138
141
  }
139
142
  >() {
140
- static layerTest = ({ functions }: { functions: FunctionDefinition<any, any>[] }) =>
143
+ static layerTest = ({ functions }: { functions: readonly FunctionDefinition<any, any>[] }) =>
141
144
  Layer.succeed(FunctionImplementationResolver, {
142
145
  resolveFunctionImplementation: <I, O>(functionDef: FunctionDefinition<I, O>) => {
143
146
  const resolved = functions.find((f) => f.key === functionDef.key);
@@ -2,7 +2,9 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Context, Effect, Layer } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
6
8
 
7
9
  import type { Obj, Relation } from '@dxos/echo';
8
10
  import type { Queue, QueueAPI, QueueFactory } from '@dxos/echo-db';
@@ -2,7 +2,9 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Context, Effect, Layer } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
6
8
 
7
9
  import type { SpaceId } from '@dxos/keys';
8
10
 
@@ -2,7 +2,8 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { type Context, Layer } from 'effect';
5
+ import type * as Context from 'effect/Context';
6
+ import * as Layer from 'effect/Layer';
6
7
 
7
8
  import { AiService } from '@dxos/ai';
8
9
  import { entries } from '@dxos/util';
@@ -3,7 +3,10 @@
3
3
  //
4
4
 
5
5
  import { describe, it } from '@effect/vitest';
6
- import { Context, Effect, Layer, Option } from 'effect';
6
+ import * as Context from 'effect/Context';
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Layer from 'effect/Layer';
9
+ import * as Option from 'effect/Option';
7
10
 
8
11
  import { ServiceRegistry } from './service-registry';
9
12
 
@@ -2,7 +2,10 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Context, Effect, type Option, flow } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Function from 'effect/Function';
8
+ import type * as Option from 'effect/Option';
6
9
 
7
10
  import { ServiceNotAvailableError } from '../errors';
8
11
 
@@ -40,7 +43,8 @@ export class ServiceRegistry extends Context.Tag('@dxos/functions/ServiceRegistr
40
43
  E | ServiceNotAvailableError,
41
44
  Exclude<R, { [K in keyof Tags]: Context.Tag.Identifier<Tags[K]> }[number]> | ServiceRegistry
42
45
  >;
43
- } = (...tags) => (flow as any)(...tags.map((tag) => Effect.provideServiceEffect(tag, ServiceRegistry.resolve(tag))));
46
+ } = (...tags) =>
47
+ (Function.flow as any)(...tags.map((tag) => Effect.provideServiceEffect(tag, ServiceRegistry.resolve(tag))));
44
48
 
45
49
  static provideOrDie: {
46
50
  <Tags extends [Context.Tag<any, any>, ...Context.Tag<any, any>[]]>(
@@ -53,7 +57,7 @@ export class ServiceRegistry extends Context.Tag('@dxos/functions/ServiceRegistr
53
57
  Exclude<R, { [K in keyof Tags]: Context.Tag.Identifier<Tags[K]> }[number]> | ServiceRegistry
54
58
  >;
55
59
  } = (...tags) =>
56
- (flow as any)(
60
+ (Function.flow as any)(
57
61
  ...tags.map((tag) => Effect.provideServiceEffect(tag, ServiceRegistry.resolve(tag).pipe(Effect.orDie))),
58
62
  );
59
63
  }
@@ -2,12 +2,14 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Context, Effect, Layer } from 'effect';
5
+ import * as Context from 'effect/Context';
6
+ import * as Effect from 'effect/Effect';
7
+ import * as Layer from 'effect/Layer';
6
8
 
7
9
  import { AgentStatus } from '@dxos/ai';
8
10
  import { Obj } from '@dxos/echo';
11
+ import type { ObjectId } from '@dxos/echo/internal';
9
12
  import type { Queue } from '@dxos/echo-db';
10
- import type { ObjectId } from '@dxos/echo-schema';
11
13
  import { log } from '@dxos/log';
12
14
  import { DataType } from '@dxos/schema';
13
15