@dxos/functions 0.8.4-main.ef1bc66f44 → 0.8.4-main.f466a3d56e

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 (79) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +5 -7
  3. package/dist/lib/neutral/index.mjs +295 -922
  4. package/dist/lib/neutral/index.mjs.map +4 -4
  5. package/dist/lib/neutral/meta.json +1 -1
  6. package/dist/types/src/index.d.ts +0 -2
  7. package/dist/types/src/index.d.ts.map +1 -1
  8. package/dist/types/src/protocol/functions-ai-http-client.d.ts.map +1 -1
  9. package/dist/types/src/protocol/functions-ai-http-client.test.d.ts +2 -0
  10. package/dist/types/src/protocol/functions-ai-http-client.test.d.ts.map +1 -0
  11. package/dist/types/src/protocol/protocol.d.ts +19 -2
  12. package/dist/types/src/protocol/protocol.d.ts.map +1 -1
  13. package/dist/types/src/sdk.d.ts +5 -109
  14. package/dist/types/src/sdk.d.ts.map +1 -1
  15. package/dist/types/src/services/credentials.d.ts +15 -38
  16. package/dist/types/src/services/credentials.d.ts.map +1 -1
  17. package/dist/types/src/services/function-invocation-service.d.ts +8 -6
  18. package/dist/types/src/services/function-invocation-service.d.ts.map +1 -1
  19. package/dist/types/src/services/index.d.ts +1 -4
  20. package/dist/types/src/services/index.d.ts.map +1 -1
  21. package/dist/types/src/services/queues.d.ts +1 -46
  22. package/dist/types/src/services/queues.d.ts.map +1 -1
  23. package/dist/types/src/services/tracing.d.ts +1 -84
  24. package/dist/types/src/services/tracing.d.ts.map +1 -1
  25. package/dist/types/src/types/index.d.ts +0 -4
  26. package/dist/types/src/types/index.d.ts.map +1 -1
  27. package/dist/types/src/types/url.d.ts +3 -3
  28. package/dist/types/src/types/url.d.ts.map +1 -1
  29. package/dist/types/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +18 -17
  31. package/src/index.ts +0 -2
  32. package/src/protocol/functions-ai-http-client.test.ts +105 -0
  33. package/src/protocol/functions-ai-http-client.ts +75 -1
  34. package/src/protocol/protocol.test.ts +9 -10
  35. package/src/protocol/protocol.ts +252 -59
  36. package/src/sdk.ts +12 -270
  37. package/src/services/credentials.ts +76 -120
  38. package/src/services/function-invocation-service.ts +9 -10
  39. package/src/services/index.ts +1 -4
  40. package/src/services/queues.ts +1 -78
  41. package/src/services/tracing.ts +0 -159
  42. package/src/types/index.ts +0 -4
  43. package/src/types/url.ts +3 -3
  44. package/dist/types/src/errors.d.ts +0 -121
  45. package/dist/types/src/errors.d.ts.map +0 -1
  46. package/dist/types/src/example/fib.d.ts +0 -7
  47. package/dist/types/src/example/fib.d.ts.map +0 -1
  48. package/dist/types/src/example/forex-effect.d.ts +0 -3
  49. package/dist/types/src/example/forex-effect.d.ts.map +0 -1
  50. package/dist/types/src/example/index.d.ts +0 -12
  51. package/dist/types/src/example/index.d.ts.map +0 -1
  52. package/dist/types/src/example/reply.d.ts +0 -3
  53. package/dist/types/src/example/reply.d.ts.map +0 -1
  54. package/dist/types/src/example/sleep.d.ts +0 -5
  55. package/dist/types/src/example/sleep.d.ts.map +0 -1
  56. package/dist/types/src/operation-compatibility.test.d.ts +0 -2
  57. package/dist/types/src/operation-compatibility.test.d.ts.map +0 -1
  58. package/dist/types/src/services/event-logger.d.ts +0 -81
  59. package/dist/types/src/services/event-logger.d.ts.map +0 -1
  60. package/dist/types/src/types/Function.d.ts +0 -52
  61. package/dist/types/src/types/Function.d.ts.map +0 -1
  62. package/dist/types/src/types/Script.d.ts +0 -21
  63. package/dist/types/src/types/Script.d.ts.map +0 -1
  64. package/dist/types/src/types/Trigger.d.ts +0 -121
  65. package/dist/types/src/types/Trigger.d.ts.map +0 -1
  66. package/dist/types/src/types/TriggerEvent.d.ts +0 -74
  67. package/dist/types/src/types/TriggerEvent.d.ts.map +0 -1
  68. package/src/errors.ts +0 -21
  69. package/src/example/fib.ts +0 -32
  70. package/src/example/forex-effect.ts +0 -40
  71. package/src/example/index.ts +0 -13
  72. package/src/example/reply.ts +0 -21
  73. package/src/example/sleep.ts +0 -24
  74. package/src/operation-compatibility.test.ts +0 -185
  75. package/src/services/event-logger.ts +0 -127
  76. package/src/types/Function.ts +0 -82
  77. package/src/types/Script.ts +0 -34
  78. package/src/types/Trigger.ts +0 -143
  79. package/src/types/TriggerEvent.ts +0 -62
@@ -1,121 +0,0 @@
1
- import * as Schema from 'effect/Schema';
2
- import { Obj, QueryAST, Type } from '@dxos/echo';
3
- /**
4
- * Type discriminator for TriggerType.
5
- * Every spec has a type field of type TriggerKind that we can use to understand which type we're working with.
6
- * https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions
7
- */
8
- export declare const Kinds: readonly ["email", "queue", "subscription", "timer", "webhook"];
9
- export type Kind = (typeof Kinds)[number];
10
- export declare const EmailSpec: Schema.Struct<{
11
- kind: Schema.Literal<["email"]>;
12
- }>;
13
- export type EmailSpec = Schema.Schema.Type<typeof EmailSpec>;
14
- export declare const QueueSpec: Schema.Struct<{
15
- kind: Schema.Literal<["queue"]>;
16
- queue: Schema.refine<string, typeof Schema.NonEmptyString>;
17
- }>;
18
- export type QueueSpec = Schema.Schema.Type<typeof QueueSpec>;
19
- /**
20
- * Subscription.
21
- */
22
- export declare const SubscriptionSpec: Schema.Struct<{
23
- kind: Schema.Literal<["subscription"]>;
24
- query: Schema.Struct<{
25
- raw: Schema.optional<Schema.SchemaClass<string, string, never>>;
26
- ast: Schema.Schema<QueryAST.QuerySelectClause | QueryAST.QueryFilterClause | QueryAST.QueryReferenceTraversalClause | QueryAST.QueryIncomingReferencesClause | QueryAST.QueryRelationClause | QueryAST.QueryRelationTraversalClause | QueryAST.QueryHierarchyTraversalClause | QueryAST.QueryUnionClause | QueryAST.QuerySetDifferenceClause | QueryAST.QueryOrderClause | QueryAST.QueryOptionsClause | QueryAST.QueryLimitClause, QueryAST.QuerySelectClause | QueryAST.QueryFilterClause | QueryAST.QueryReferenceTraversalClause | QueryAST.QueryIncomingReferencesClause | QueryAST.QueryRelationClause | QueryAST.QueryRelationTraversalClause | QueryAST.QueryHierarchyTraversalClause | QueryAST.QueryUnionClause | QueryAST.QuerySetDifferenceClause | QueryAST.QueryOrderClause | QueryAST.QueryOptionsClause | QueryAST.QueryLimitClause, never>;
27
- }>;
28
- options: Schema.optional<Schema.Struct<{
29
- deep: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
30
- delay: Schema.optional<Schema.SchemaClass<number, number, never>>;
31
- }>>;
32
- }>;
33
- export type SubscriptionSpec = Schema.Schema.Type<typeof SubscriptionSpec>;
34
- /**
35
- * Cron timer.
36
- */
37
- export declare const TimerSpec: Schema.Struct<{
38
- kind: Schema.Literal<["timer"]>;
39
- cron: Schema.SchemaClass<string, string, never>;
40
- }>;
41
- export type TimerSpec = Schema.Schema.Type<typeof TimerSpec>;
42
- /**
43
- * Webhook.
44
- */
45
- export declare const WebhookSpec: Schema.Struct<{
46
- kind: Schema.Literal<["webhook"]>;
47
- method: Schema.optional<Schema.SchemaClass<string, string, never>>;
48
- port: Schema.optional<Schema.SchemaClass<number, number, never>>;
49
- }>;
50
- export type WebhookSpec = Schema.Schema.Type<typeof WebhookSpec>;
51
- /**
52
- * Trigger schema.
53
- */
54
- export declare const Spec: Schema.Union<[Schema.Struct<{
55
- kind: Schema.Literal<["email"]>;
56
- }>, Schema.Struct<{
57
- kind: Schema.Literal<["queue"]>;
58
- queue: Schema.refine<string, typeof Schema.NonEmptyString>;
59
- }>, Schema.Struct<{
60
- kind: Schema.Literal<["subscription"]>;
61
- query: Schema.Struct<{
62
- raw: Schema.optional<Schema.SchemaClass<string, string, never>>;
63
- ast: Schema.Schema<QueryAST.QuerySelectClause | QueryAST.QueryFilterClause | QueryAST.QueryReferenceTraversalClause | QueryAST.QueryIncomingReferencesClause | QueryAST.QueryRelationClause | QueryAST.QueryRelationTraversalClause | QueryAST.QueryHierarchyTraversalClause | QueryAST.QueryUnionClause | QueryAST.QuerySetDifferenceClause | QueryAST.QueryOrderClause | QueryAST.QueryOptionsClause | QueryAST.QueryLimitClause, QueryAST.QuerySelectClause | QueryAST.QueryFilterClause | QueryAST.QueryReferenceTraversalClause | QueryAST.QueryIncomingReferencesClause | QueryAST.QueryRelationClause | QueryAST.QueryRelationTraversalClause | QueryAST.QueryHierarchyTraversalClause | QueryAST.QueryUnionClause | QueryAST.QuerySetDifferenceClause | QueryAST.QueryOrderClause | QueryAST.QueryOptionsClause | QueryAST.QueryLimitClause, never>;
64
- }>;
65
- options: Schema.optional<Schema.Struct<{
66
- deep: Schema.optional<Schema.SchemaClass<boolean, boolean, never>>;
67
- delay: Schema.optional<Schema.SchemaClass<number, number, never>>;
68
- }>>;
69
- }>, Schema.Struct<{
70
- kind: Schema.Literal<["timer"]>;
71
- cron: Schema.SchemaClass<string, string, never>;
72
- }>, Schema.Struct<{
73
- kind: Schema.Literal<["webhook"]>;
74
- method: Schema.optional<Schema.SchemaClass<string, string, never>>;
75
- port: Schema.optional<Schema.SchemaClass<number, number, never>>;
76
- }>]>;
77
- export type Spec = Schema.Schema.Type<typeof Spec>;
78
- /**
79
- * Function trigger.
80
- * Function is invoked with the `payload` passed as input data.
81
- * The event that triggers the function is available in the function context.
82
- */
83
- declare const TriggerSchema: Type.Obj<{
84
- readonly function?: import("@dxos/echo/internal").Ref<import("@dxos/echo/Entity").OfKind<import("@dxos/echo/internal").EntityKind.Object> & {
85
- readonly [x: string]: any;
86
- }> | undefined;
87
- readonly inputNodeId?: string | undefined;
88
- readonly enabled?: boolean | undefined;
89
- readonly spec?: {
90
- readonly kind: "email";
91
- } | {
92
- readonly queue: string;
93
- readonly kind: "queue";
94
- } | {
95
- readonly kind: "subscription";
96
- readonly query: {
97
- readonly raw?: string | undefined;
98
- readonly ast: QueryAST.QuerySelectClause | QueryAST.QueryFilterClause | QueryAST.QueryReferenceTraversalClause | QueryAST.QueryIncomingReferencesClause | QueryAST.QueryRelationClause | QueryAST.QueryRelationTraversalClause | QueryAST.QueryHierarchyTraversalClause | QueryAST.QueryUnionClause | QueryAST.QuerySetDifferenceClause | QueryAST.QueryOrderClause | QueryAST.QueryOptionsClause | QueryAST.QueryLimitClause;
99
- };
100
- readonly options?: {
101
- readonly deep?: boolean | undefined;
102
- readonly delay?: number | undefined;
103
- } | undefined;
104
- } | {
105
- readonly kind: "timer";
106
- readonly cron: string;
107
- } | {
108
- readonly kind: "webhook";
109
- readonly method?: string | undefined;
110
- readonly port?: number | undefined;
111
- } | undefined;
112
- readonly input?: {
113
- readonly [x: string]: any;
114
- } | undefined;
115
- }, Schema.Struct.Fields>;
116
- export interface Trigger extends Schema.Schema.Type<typeof TriggerSchema> {
117
- }
118
- export declare const Trigger: Type.Obj<Trigger>;
119
- export declare const make: (props: Obj.MakeProps<typeof Trigger>) => Obj.Obj<import("@dxos/echo/Entity").OfKind<import("@dxos/echo/internal").EntityKind.Object> & Trigger>;
120
- export {};
121
- //# sourceMappingURL=Trigger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Trigger.d.ts","sourceRoot":"","sources":["../../../../src/types/Trigger.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAKjD;;;;GAIG;AACH,eAAO,MAAM,KAAK,iEAAkE,CAAC;AACrF,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AAI1C,eAAO,MAAM,SAAS;;EAEpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;AAE7D,eAAO,MAAM,SAAS;;;EAKpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;EAc3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,SAAS;;;EAMpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,WAAW;;;;EAatB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;IAEf,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnD;;;;GAIG;AACH,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAsClB,CAAC;AAEF,MAAM,WAAW,OAAQ,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,aAAa,CAAC;CAAG;AAC5E,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAwB,CAAC;AAE/D,eAAO,MAAM,IAAI,GAAI,OAAO,GAAG,CAAC,SAAS,CAAC,OAAO,OAAO,CAAC,2GAA6B,CAAC"}
@@ -1,74 +0,0 @@
1
- import * as Schema from 'effect/Schema';
2
- export declare const EmailEvent: Schema.Struct<{
3
- from: typeof Schema.String;
4
- to: typeof Schema.String;
5
- subject: typeof Schema.String;
6
- created: typeof Schema.String;
7
- body: typeof Schema.String;
8
- }>;
9
- export type EmailEvent = Schema.Schema.Type<typeof EmailEvent>;
10
- export declare const QueueEvent: Schema.Struct<{
11
- queue: Schema.refine<string, typeof Schema.NonEmptyString>;
12
- item: typeof Schema.Any;
13
- cursor: typeof Schema.String;
14
- }>;
15
- export type QueueEvent = Schema.Schema.Type<typeof QueueEvent>;
16
- export declare const SubscriptionEvent: Schema.Struct<{
17
- /**
18
- * Type of the mutation.
19
- */
20
- type: typeof Schema.String;
21
- /**
22
- * Reference to the object that was changed or created.
23
- */
24
- subject: import("@dxos/echo/internal").RefSchema<any>;
25
- /**
26
- * @deprecated
27
- */
28
- changedObjectId: Schema.optional<typeof Schema.String>;
29
- }>;
30
- export type SubscriptionEvent = Schema.Schema.Type<typeof SubscriptionEvent>;
31
- export declare const TimerEvent: Schema.Struct<{
32
- tick: typeof Schema.Number;
33
- }>;
34
- export type TimerEvent = Schema.Schema.Type<typeof TimerEvent>;
35
- export declare const WebhookEvent: Schema.Struct<{
36
- url: typeof Schema.String;
37
- method: Schema.Literal<["GET", "POST"]>;
38
- headers: Schema.Record$<typeof Schema.String, typeof Schema.String>;
39
- bodyText: typeof Schema.String;
40
- }>;
41
- export type WebhookEvent = Schema.Schema.Type<typeof WebhookEvent>;
42
- export declare const TriggerEvent: Schema.Union<[Schema.Struct<{
43
- from: typeof Schema.String;
44
- to: typeof Schema.String;
45
- subject: typeof Schema.String;
46
- created: typeof Schema.String;
47
- body: typeof Schema.String;
48
- }>, Schema.Struct<{
49
- queue: Schema.refine<string, typeof Schema.NonEmptyString>;
50
- item: typeof Schema.Any;
51
- cursor: typeof Schema.String;
52
- }>, Schema.Struct<{
53
- /**
54
- * Type of the mutation.
55
- */
56
- type: typeof Schema.String;
57
- /**
58
- * Reference to the object that was changed or created.
59
- */
60
- subject: import("@dxos/echo/internal").RefSchema<any>;
61
- /**
62
- * @deprecated
63
- */
64
- changedObjectId: Schema.optional<typeof Schema.String>;
65
- }>, Schema.Struct<{
66
- tick: typeof Schema.Number;
67
- }>, Schema.Struct<{
68
- url: typeof Schema.String;
69
- method: Schema.Literal<["GET", "POST"]>;
70
- headers: Schema.Record$<typeof Schema.String, typeof Schema.String>;
71
- bodyText: typeof Schema.String;
72
- }>]>;
73
- export type TriggerEvent = Schema.Schema.Type<typeof TriggerEvent>;
74
- //# sourceMappingURL=TriggerEvent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TriggerEvent.d.ts","sourceRoot":"","sources":["../../../../src/types/TriggerEvent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAUxC,eAAO,MAAM,UAAU;;;;;;EAMrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,UAAU,CAAC,CAAC;AAE/D,eAAO,MAAM,UAAU;;;;EAIrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,UAAU,CAAC,CAAC;AAE/D,eAAO,MAAM,iBAAiB;IAC5B;;OAEG;;IAIH;;OAEG;;IAGH;;OAEG;;EAEH,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE7E,eAAO,MAAM,UAAU;;EAAyC,CAAC;AACjE,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,UAAU,CAAC,CAAC;AAE/D,eAAO,MAAM,YAAY;;;;;EAKvB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC,CAAC;AAEnE,eAAO,MAAM,YAAY;;;;;;;;;;;IA7BvB;;OAEG;;IAIH;;OAEG;;IAGH;;OAEG;;;;;;;;;IAgBwG,CAAC;AAC9G,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC,CAAC"}
package/src/errors.ts DELETED
@@ -1,21 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { BaseError, type BaseErrorOptions } from '@dxos/errors';
6
-
7
- export class ServiceNotAvailableError extends BaseError.extend('ServiceNotAvailable', 'Service not available') {
8
- constructor(service: string, options?: Omit<BaseErrorOptions, 'context'>) {
9
- super({ context: { service }, ...options });
10
- }
11
- }
12
-
13
- export class FunctionNotFoundError extends BaseError.extend('FunctionNotFound', 'Function not found') {
14
- constructor(functionKey: string, options?: Omit<BaseErrorOptions, 'context'>) {
15
- super({ context: { function: functionKey }, ...options });
16
- }
17
- }
18
-
19
- export class FunctionError extends BaseError.extend('FunctionError', 'Function invocation error') {}
20
-
21
- export class TriggerStateNotFoundError extends BaseError.extend('TriggerStateNotFound', 'Trigger state not found') {}
@@ -1,32 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import * as Effect from 'effect/Effect';
6
- import * as Schema from 'effect/Schema';
7
-
8
- import { defineFunction } from '../sdk';
9
-
10
- export default defineFunction({
11
- key: 'example.org/function/fib',
12
- name: 'Fibonacci',
13
- description: 'Function that calculates a Fibonacci number',
14
- inputSchema: Schema.Struct({
15
- iterations: Schema.optional(Schema.Number).annotations({
16
- description: 'Number of iterations',
17
- default: 100_000,
18
- }),
19
- }),
20
- outputSchema: Schema.Struct({
21
- result: Schema.String,
22
- }),
23
- handler: Effect.fn(function* ({ data: { iterations = 100_000 } }) {
24
- let a = 0n;
25
- let b = 1n;
26
- for (let i = 0; i < iterations; i++) {
27
- a += b;
28
- b = a - b;
29
- }
30
- return { result: a.toString() };
31
- }),
32
- });
@@ -1,40 +0,0 @@
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
- });
@@ -1,13 +0,0 @@
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
- }
@@ -1,21 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import * as Console from 'effect/Console';
6
- import * as Effect from 'effect/Effect';
7
- import * as Schema from 'effect/Schema';
8
-
9
- import { defineFunction } from '../sdk';
10
-
11
- export default defineFunction({
12
- key: 'example.org/function/reply',
13
- name: 'Reply',
14
- description: 'Function that echoes the input',
15
- inputSchema: Schema.Any,
16
- outputSchema: Schema.Any,
17
- handler: Effect.fn(function* ({ data }) {
18
- yield* Console.log('reply', { data });
19
- return data;
20
- }),
21
- });
@@ -1,24 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import * as Effect from 'effect/Effect';
6
- import * as Schema from 'effect/Schema';
7
-
8
- import { defineFunction } from '../sdk';
9
-
10
- export default defineFunction({
11
- key: 'example.org/function/sleep',
12
- name: 'Sleep',
13
- description: 'Function that sleeps for a given amount of time',
14
- inputSchema: Schema.Struct({
15
- duration: Schema.optional(Schema.Number).annotations({
16
- description: 'Milliseconds to sleep',
17
- default: 100_000,
18
- }),
19
- }),
20
- outputSchema: Schema.Void,
21
- handler: Effect.fn(function* ({ data: { duration = 100_000 } }) {
22
- yield* Effect.sleep(duration);
23
- }),
24
- });
@@ -1,185 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import * as Effect from 'effect/Effect';
6
- import * as Schema from 'effect/Schema';
7
- import { describe, expect, test } from 'vitest';
8
-
9
- import { FunctionDefinition, defineFunction } from './sdk';
10
-
11
- describe('Function/Operation Compatibility', () => {
12
- test('can convert FunctionDefinition to OperationDefinition', () => {
13
- const func = defineFunction({
14
- key: 'test.function',
15
- name: 'Test Function',
16
- description: 'A test function',
17
- inputSchema: Schema.Struct({ value: Schema.Number }),
18
- outputSchema: Schema.Struct({ result: Schema.String }),
19
- handler: async ({ data }) => {
20
- return { result: data.value.toString() };
21
- },
22
- });
23
-
24
- const op = FunctionDefinition.toOperation(func);
25
-
26
- expect(op.meta.key).toBe('test.function');
27
- expect(op.meta.name).toBe('Test Function');
28
- expect(op.meta.description).toBe('A test function');
29
- expect(Schema.isSchema(op.schema.input)).toBe(true);
30
- expect(Schema.isSchema(op.schema.output)).toBe(true);
31
- });
32
-
33
- test('converted operation has matching schemas', () => {
34
- const inputSchema = Schema.Struct({
35
- name: Schema.String,
36
- age: Schema.Number,
37
- });
38
- const outputSchema = Schema.Struct({
39
- greeting: Schema.String,
40
- });
41
-
42
- const func = defineFunction({
43
- key: 'test.greet',
44
- name: 'Greet',
45
- inputSchema,
46
- outputSchema,
47
- handler: async ({ data }) => {
48
- return { greeting: `Hello, ${data.name}!` };
49
- },
50
- });
51
-
52
- const op = FunctionDefinition.toOperation(func);
53
-
54
- // Verify schemas match
55
- const testInput = { name: 'Alice', age: 30 };
56
- const validatedInput = Schema.decodeSync(op.schema.input)(testInput);
57
- expect(validatedInput).toEqual(testInput);
58
-
59
- const testOutput = { greeting: 'Hello, Alice!' };
60
- const validatedOutput = Schema.decodeSync(op.schema.output)(testOutput);
61
- expect(validatedOutput).toEqual(testOutput);
62
- });
63
-
64
- test('converted operation preserves metadata', () => {
65
- const func = defineFunction({
66
- key: 'test.meta',
67
- name: 'Meta Test',
68
- description: 'Tests metadata preservation',
69
- inputSchema: Schema.Void,
70
- outputSchema: Schema.Void,
71
- handler: async () => {},
72
- });
73
-
74
- const op = FunctionDefinition.toOperation(func);
75
-
76
- expect(op.meta.key).toBe('test.meta');
77
- expect(op.meta.name).toBe('Meta Test');
78
- expect(op.meta.description).toBe('Tests metadata preservation');
79
- });
80
-
81
- test('converted operation is pipeable', () => {
82
- const func = defineFunction({
83
- key: 'test.pipe',
84
- name: 'Pipe Test',
85
- inputSchema: Schema.Void,
86
- outputSchema: Schema.Void,
87
- handler: async () => {},
88
- });
89
-
90
- const op = FunctionDefinition.toOperation(func);
91
-
92
- expect(typeof op.pipe).toBe('function');
93
- });
94
-
95
- test('handles functions without output schema', () => {
96
- const func = defineFunction({
97
- key: 'test.no-output',
98
- name: 'No Output',
99
- inputSchema: Schema.Struct({ value: Schema.Number }),
100
- handler: async ({ data }) => {
101
- return data.value * 2;
102
- },
103
- });
104
-
105
- const op = FunctionDefinition.toOperation(func);
106
-
107
- expect(op.meta.key).toBe('test.no-output');
108
- expect(Schema.isSchema(op.schema.output)).toBe(true);
109
- });
110
-
111
- test('converted operation includes handler', () => {
112
- const func = defineFunction({
113
- key: 'test.handler',
114
- name: 'Handler Test',
115
- inputSchema: Schema.Struct({ value: Schema.Number }),
116
- outputSchema: Schema.Struct({ doubled: Schema.Number }),
117
- handler: async ({ data }) => {
118
- return { doubled: data.value * 2 };
119
- },
120
- });
121
-
122
- const op = FunctionDefinition.toOperation(func);
123
-
124
- expect(op.handler).toBeDefined();
125
- expect(typeof op.handler).toBe('function');
126
- });
127
-
128
- test('converted operation has handler function', () => {
129
- const func = defineFunction({
130
- key: 'test.execute',
131
- name: 'Execute Test',
132
- inputSchema: Schema.Struct({ value: Schema.Number }),
133
- outputSchema: Schema.Struct({ result: Schema.Number }),
134
- handler: async ({ data }) => {
135
- return { result: data.value * 3 };
136
- },
137
- });
138
-
139
- const op = FunctionDefinition.toOperation(func);
140
-
141
- // Handler is present and is a function that returns an Effect
142
- expect(op.handler).toBeDefined();
143
- const effect = op.handler({ value: 5 });
144
- // Verify it returns an Effect-like object
145
- expect(effect).toHaveProperty('pipe');
146
- });
147
-
148
- test('converted operation works with Effect-based handlers', () => {
149
- const func = defineFunction({
150
- key: 'test.effect',
151
- name: 'Effect Test',
152
- inputSchema: Schema.Struct({ value: Schema.Number }),
153
- outputSchema: Schema.Struct({ result: Schema.Number }),
154
- handler: Effect.fn(function* ({ data }) {
155
- return { result: data.value * 4 };
156
- }),
157
- });
158
-
159
- const op = FunctionDefinition.toOperation(func);
160
-
161
- // Handler is present and produces an Effect
162
- expect(op.handler).toBeDefined();
163
- const effect = op.handler({ value: 3 });
164
- expect(effect).toHaveProperty('pipe');
165
- });
166
-
167
- test('converted operation works with synchronous handlers', () => {
168
- const func = defineFunction({
169
- key: 'test.sync',
170
- name: 'Sync Test',
171
- inputSchema: Schema.Struct({ value: Schema.Number }),
172
- outputSchema: Schema.Struct({ result: Schema.Number }),
173
- handler: ({ data }) => {
174
- return { result: data.value * 5 };
175
- },
176
- });
177
-
178
- const op = FunctionDefinition.toOperation(func);
179
-
180
- // Handler is present and produces an Effect
181
- expect(op.handler).toBeDefined();
182
- const effect = op.handler({ value: 2 });
183
- expect(effect).toHaveProperty('pipe');
184
- });
185
- });
@@ -1,127 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
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';
9
-
10
- import { Obj, Type } from '@dxos/echo';
11
- import { invariant } from '@dxos/invariant';
12
- import { LogLevel, log } from '@dxos/log';
13
-
14
- import { TracingService } from './tracing';
15
-
16
- export const ComputeEventPayload = Schema.Union(
17
- Schema.Struct({
18
- type: Schema.Literal('begin-compute'),
19
- nodeId: Schema.String,
20
- /**
21
- * Names of the inputs begin computed.
22
- */
23
- inputs: Schema.Array(Schema.String),
24
- }),
25
- Schema.Struct({
26
- type: Schema.Literal('end-compute'),
27
- nodeId: Schema.String,
28
- /**
29
- * Names of the outputs computed.
30
- */
31
- outputs: Schema.Array(Schema.String),
32
- }),
33
- Schema.Struct({
34
- type: Schema.Literal('compute-input'),
35
- nodeId: Schema.String,
36
- property: Schema.String,
37
- value: Schema.Any,
38
- }),
39
- Schema.Struct({
40
- type: Schema.Literal('compute-output'),
41
- nodeId: Schema.String,
42
- property: Schema.String,
43
- value: Schema.Any,
44
- }),
45
- Schema.Struct({
46
- type: Schema.Literal('custom'),
47
- nodeId: Schema.String,
48
- event: Schema.Any,
49
- }),
50
- );
51
- export type ComputeEventPayload = Schema.Schema.Type<typeof ComputeEventPayload>;
52
-
53
- export const ComputeEvent = Schema.Struct({
54
- payload: ComputeEventPayload,
55
- }).pipe(Type.object({ typename: 'dxos.org/type/ComputeEvent', version: '0.1.0' }));
56
-
57
- /**
58
- * Logs event for the compute workflows.
59
- */
60
- export class ComputeEventLogger extends Context.Tag('@dxos/functions/ComputeEventLogger')<
61
- ComputeEventLogger,
62
- { readonly log: (event: ComputeEventPayload) => void; readonly nodeId: string | undefined }
63
- >() {
64
- static noop: Context.Tag.Service<ComputeEventLogger> = {
65
- log: () => {},
66
- nodeId: undefined,
67
- };
68
-
69
- /**
70
- * Implements ComputeEventLogger using TracingService.
71
- */
72
- static layerFromTracing = Layer.effect(
73
- ComputeEventLogger,
74
- Effect.gen(function* () {
75
- const tracing = yield* TracingService;
76
- return {
77
- log: (event: ComputeEventPayload) => {
78
- tracing.write(Obj.make(ComputeEvent, { payload: event }), tracing.getTraceContext());
79
- },
80
- nodeId: undefined,
81
- };
82
- }),
83
- );
84
- }
85
-
86
- export const logCustomEvent = (data: any) =>
87
- Effect.gen(function* () {
88
- const logger = yield* ComputeEventLogger;
89
- if (!logger.nodeId) {
90
- throw new Error('logCustomEvent must be called within a node compute function');
91
- }
92
- logger.log({
93
- type: 'custom',
94
- nodeId: logger.nodeId,
95
- event: data,
96
- });
97
- });
98
-
99
- export const createDefectLogger = <A, E, R>(): ((self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>) =>
100
- Effect.catchAll((error) =>
101
- Effect.gen(function* () {
102
- log.error('unhandled effect error', { error });
103
- throw error;
104
- }),
105
- );
106
-
107
- export const createEventLogger = (
108
- level: LogLevel,
109
- message: string = 'event',
110
- ): Context.Tag.Service<ComputeEventLogger> => {
111
- const logFunction = (
112
- {
113
- [LogLevel.WARN]: log.warn,
114
- [LogLevel.VERBOSE]: log.verbose,
115
- [LogLevel.DEBUG]: log.debug,
116
- [LogLevel.INFO]: log.info,
117
- [LogLevel.ERROR]: log.error,
118
- } as any
119
- )[level];
120
- invariant(logFunction);
121
- return {
122
- log: (event: ComputeEventPayload) => {
123
- logFunction(message, event);
124
- },
125
- nodeId: undefined,
126
- };
127
- };