@restatedev/restate-sdk-clients 1.15.0-rc.7 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.d.cts CHANGED
@@ -55,6 +55,19 @@ interface Ingress {
55
55
  handler: string;
56
56
  parameter: I$1;
57
57
  key?: string;
58
+ /**
59
+ * Route this call within the given scope. See {@link Ingress.scope}.
60
+ *
61
+ * *NOTE:* This API is experimental. To use it you need a restate-server >= 1.7,
62
+ * configured to enable
63
+ * [service protocol v7](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#service-protocol-v7)
64
+ * and [flow control](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#flow-control).
65
+ * For example, start the restate-server with the environment variables
66
+ * `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.
67
+ *
68
+ * @experimental
69
+ */
70
+ scope?: string;
58
71
  opts?: Opts<I$1, O$1>;
59
72
  }): Promise<O$1>;
60
73
  /** Generic fire-and-forget send. Routes directly by service name without a typed definition. */
@@ -63,9 +76,72 @@ interface Ingress {
63
76
  handler: string;
64
77
  parameter: I$1;
65
78
  key?: string;
79
+ /**
80
+ * Route this send within the given scope. See {@link Ingress.scope}.
81
+ *
82
+ * *NOTE:* This API is experimental. To use it you need a restate-server >= 1.7,
83
+ * configured to enable
84
+ * [service protocol v7](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#service-protocol-v7)
85
+ * and [flow control](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#flow-control).
86
+ * For example, start the restate-server with the environment variables
87
+ * `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.
88
+ *
89
+ * @experimental
90
+ */
91
+ scope?: string;
66
92
  opts?: SendOpts<I$1>;
67
93
  }): Promise<Send>;
94
+ /**
95
+ * Returns a {@link ScopedIngress} that routes all calls within the given scope.
96
+ *
97
+ * **NOTE:** This API is in preview and is not enabled by default.
98
+ * To use it in restate-server 1.7, enable the flow control and protocol v7 experimental features,
99
+ * via `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.
100
+ * These can be enabled only on **new clusters**, for more info check out https://docs.restate.dev/services/flow-control#enabling-flow-control.
101
+ * If these experimental features aren't enabled, the invocation won't be ingested and the client request fails.
102
+ *
103
+ * A scope is a sub-grouping of resources (invocations, virtual object instances, workflow
104
+ * instances, concurrency limits) within the Restate cluster.
105
+ * It becomes part of the target identity tuple:
106
+ * - `scope, service, handler, idempotencyKey?`
107
+ * - `scope, virtualObject, objectKey, handler, idempotencyKey?`
108
+ * - `scope, workflow, workflowKey, handler`
109
+ *
110
+ * Under the hood, the scope contributes to the partition key, so all resources in a scope get co-located by the restate-server.
111
+ *
112
+ * Omitting the scope (i.e. using the regular `serviceClient` / `workflowClient` methods)
113
+ * is equivalent to calling with no scope, which is the existing behavior.
114
+ *
115
+ * The scope key must consist only of `[a-zA-Z0-9_.-]` characters, with 1 <= length <= 36 chars.
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * // Route a call into a named scope
120
+ * await ingress.scope("tenant-123").serviceClient(MyService).process(payload);
121
+ *
122
+ * // Idempotency keys are scoped — "req-1" in "tenant-123" is distinct from "req-1" in "tenant-456"
123
+ * await ingress.scope("tenant-123").serviceClient(MyService)
124
+ * .process(payload, rpc.opts({ idempotencyKey: "req-1" }));
125
+ *
126
+ * // Combine with a limit key to enforce per-scope concurrency limits
127
+ * await ingress.scope("tenant-123").workflowClient(MyWorkflow, "wf-key")
128
+ * .run(input, rpc.opts({ limitKey: "api-key/user42" }));
129
+ * ```
130
+ *
131
+ * @param scopeKey the scope identifier
132
+ * @see https://docs.restate.dev/services/flow-control
133
+ * @experimental
134
+ */
135
+ scope(scopeKey: string): ScopedIngress;
68
136
  }
137
+ /**
138
+ * An ingress client for making RPC calls within a specific scope.
139
+ *
140
+ * @see {@link Ingress.scope}
141
+ * @experimental
142
+ * @interface
143
+ */
144
+ type ScopedIngress = Pick<Ingress, "serviceClient" | "serviceSendClient" | "workflowClient">;
69
145
  interface IngressCallOptions<I$1 = unknown, O$1 = unknown> {
70
146
  /**
71
147
  * Key to use for idempotency key.
@@ -73,6 +149,27 @@ interface IngressCallOptions<I$1 = unknown, O$1 = unknown> {
73
149
  * See https://docs.restate.dev/operate/invocation#invoke-a-handler-idempotently for more details.
74
150
  */
75
151
  idempotencyKey?: string;
152
+ /**
153
+ * An optional concurrency limit key within the scope.
154
+ * A limit key can only be used in conjunction with a scope (see {@link Ingress.scope}).
155
+ *
156
+ * **NOTE:** This API is in preview and is not enabled by default.
157
+ * To use it in restate-server 1.7, enable the flow control and protocol v7 experimental features,
158
+ * via `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.
159
+ * These can be enabled only on **new clusters**, for more info check out https://docs.restate.dev/services/flow-control#enabling-flow-control.
160
+ * If these experimental features aren't enabled, the invocation isn't ingested and the client request fails.
161
+ *
162
+ * The limit key enforces hierarchical concurrency limits on invocations sharing the same scope.
163
+ * It can have one or two levels separated by `/` (e.g. `"tenant1"` or `"tenant1/user42"`).
164
+ * Each level must consist only of `[a-zA-Z0-9_.-]` characters, and 1 <= length <= 36.
165
+ *
166
+ * The limit key is **not** part of the request identity: two calls to the same target with the
167
+ * same scope and object key but different limit keys refer to the **same** resource instance.
168
+ * The limit key only affects concurrency limits, not resource identity.
169
+ *
170
+ * @experimental
171
+ */
172
+ limitKey?: string;
76
173
  /**
77
174
  * Headers to attach to the request.
78
175
  */
@@ -244,5 +341,5 @@ type ConnectionOpts = {
244
341
  journalValueCodec?: JournalValueCodec;
245
342
  };
246
343
  //#endregion
247
- export { ConnectionOpts, InferArgType, Ingress, IngressCallOptions, IngressClient, IngressSendClient, IngressSendOptions, IngressWorkflowClient, Opts, Output, Send, SendOpts, WorkflowSubmission, rpc };
344
+ export { ConnectionOpts, InferArgType, Ingress, IngressCallOptions, IngressClient, IngressSendClient, IngressSendOptions, IngressWorkflowClient, Opts, Output, ScopedIngress, Send, SendOpts, WorkflowSubmission, rpc };
248
345
  //# sourceMappingURL=api.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.cts","names":[],"sources":["../src/api.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.cts","names":[],"sources":["../src/api.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/api.d.ts CHANGED
@@ -55,6 +55,19 @@ interface Ingress {
55
55
  handler: string;
56
56
  parameter: I$1;
57
57
  key?: string;
58
+ /**
59
+ * Route this call within the given scope. See {@link Ingress.scope}.
60
+ *
61
+ * *NOTE:* This API is experimental. To use it you need a restate-server >= 1.7,
62
+ * configured to enable
63
+ * [service protocol v7](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#service-protocol-v7)
64
+ * and [flow control](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#flow-control).
65
+ * For example, start the restate-server with the environment variables
66
+ * `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.
67
+ *
68
+ * @experimental
69
+ */
70
+ scope?: string;
58
71
  opts?: Opts<I$1, O$1>;
59
72
  }): Promise<O$1>;
60
73
  /** Generic fire-and-forget send. Routes directly by service name without a typed definition. */
@@ -63,9 +76,72 @@ interface Ingress {
63
76
  handler: string;
64
77
  parameter: I$1;
65
78
  key?: string;
79
+ /**
80
+ * Route this send within the given scope. See {@link Ingress.scope}.
81
+ *
82
+ * *NOTE:* This API is experimental. To use it you need a restate-server >= 1.7,
83
+ * configured to enable
84
+ * [service protocol v7](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#service-protocol-v7)
85
+ * and [flow control](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#flow-control).
86
+ * For example, start the restate-server with the environment variables
87
+ * `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.
88
+ *
89
+ * @experimental
90
+ */
91
+ scope?: string;
66
92
  opts?: SendOpts<I$1>;
67
93
  }): Promise<Send>;
94
+ /**
95
+ * Returns a {@link ScopedIngress} that routes all calls within the given scope.
96
+ *
97
+ * **NOTE:** This API is in preview and is not enabled by default.
98
+ * To use it in restate-server 1.7, enable the flow control and protocol v7 experimental features,
99
+ * via `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.
100
+ * These can be enabled only on **new clusters**, for more info check out https://docs.restate.dev/services/flow-control#enabling-flow-control.
101
+ * If these experimental features aren't enabled, the invocation won't be ingested and the client request fails.
102
+ *
103
+ * A scope is a sub-grouping of resources (invocations, virtual object instances, workflow
104
+ * instances, concurrency limits) within the Restate cluster.
105
+ * It becomes part of the target identity tuple:
106
+ * - `scope, service, handler, idempotencyKey?`
107
+ * - `scope, virtualObject, objectKey, handler, idempotencyKey?`
108
+ * - `scope, workflow, workflowKey, handler`
109
+ *
110
+ * Under the hood, the scope contributes to the partition key, so all resources in a scope get co-located by the restate-server.
111
+ *
112
+ * Omitting the scope (i.e. using the regular `serviceClient` / `workflowClient` methods)
113
+ * is equivalent to calling with no scope, which is the existing behavior.
114
+ *
115
+ * The scope key must consist only of `[a-zA-Z0-9_.-]` characters, with 1 <= length <= 36 chars.
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * // Route a call into a named scope
120
+ * await ingress.scope("tenant-123").serviceClient(MyService).process(payload);
121
+ *
122
+ * // Idempotency keys are scoped — "req-1" in "tenant-123" is distinct from "req-1" in "tenant-456"
123
+ * await ingress.scope("tenant-123").serviceClient(MyService)
124
+ * .process(payload, rpc.opts({ idempotencyKey: "req-1" }));
125
+ *
126
+ * // Combine with a limit key to enforce per-scope concurrency limits
127
+ * await ingress.scope("tenant-123").workflowClient(MyWorkflow, "wf-key")
128
+ * .run(input, rpc.opts({ limitKey: "api-key/user42" }));
129
+ * ```
130
+ *
131
+ * @param scopeKey the scope identifier
132
+ * @see https://docs.restate.dev/services/flow-control
133
+ * @experimental
134
+ */
135
+ scope(scopeKey: string): ScopedIngress;
68
136
  }
137
+ /**
138
+ * An ingress client for making RPC calls within a specific scope.
139
+ *
140
+ * @see {@link Ingress.scope}
141
+ * @experimental
142
+ * @interface
143
+ */
144
+ type ScopedIngress = Pick<Ingress, "serviceClient" | "serviceSendClient" | "workflowClient">;
69
145
  interface IngressCallOptions<I$1 = unknown, O$1 = unknown> {
70
146
  /**
71
147
  * Key to use for idempotency key.
@@ -73,6 +149,27 @@ interface IngressCallOptions<I$1 = unknown, O$1 = unknown> {
73
149
  * See https://docs.restate.dev/operate/invocation#invoke-a-handler-idempotently for more details.
74
150
  */
75
151
  idempotencyKey?: string;
152
+ /**
153
+ * An optional concurrency limit key within the scope.
154
+ * A limit key can only be used in conjunction with a scope (see {@link Ingress.scope}).
155
+ *
156
+ * **NOTE:** This API is in preview and is not enabled by default.
157
+ * To use it in restate-server 1.7, enable the flow control and protocol v7 experimental features,
158
+ * via `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.
159
+ * These can be enabled only on **new clusters**, for more info check out https://docs.restate.dev/services/flow-control#enabling-flow-control.
160
+ * If these experimental features aren't enabled, the invocation isn't ingested and the client request fails.
161
+ *
162
+ * The limit key enforces hierarchical concurrency limits on invocations sharing the same scope.
163
+ * It can have one or two levels separated by `/` (e.g. `"tenant1"` or `"tenant1/user42"`).
164
+ * Each level must consist only of `[a-zA-Z0-9_.-]` characters, and 1 <= length <= 36.
165
+ *
166
+ * The limit key is **not** part of the request identity: two calls to the same target with the
167
+ * same scope and object key but different limit keys refer to the **same** resource instance.
168
+ * The limit key only affects concurrency limits, not resource identity.
169
+ *
170
+ * @experimental
171
+ */
172
+ limitKey?: string;
76
173
  /**
77
174
  * Headers to attach to the request.
78
175
  */
@@ -244,5 +341,5 @@ type ConnectionOpts = {
244
341
  journalValueCodec?: JournalValueCodec;
245
342
  };
246
343
  //#endregion
247
- export { ConnectionOpts, InferArgType, Ingress, IngressCallOptions, IngressClient, IngressSendClient, IngressSendOptions, IngressWorkflowClient, Opts, Output, Send, SendOpts, WorkflowSubmission, rpc };
344
+ export { ConnectionOpts, InferArgType, Ingress, IngressCallOptions, IngressClient, IngressSendClient, IngressSendOptions, IngressWorkflowClient, Opts, Output, ScopedIngress, Send, SendOpts, WorkflowSubmission, rpc };
248
345
  //# sourceMappingURL=api.d.ts.map
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","names":[],"sources":["../src/api.ts"],"sourcesContent":[],"mappings":";;;;;;AAwBA;;;;;;;AAYU,UAZO,OAAA,CAYP;EAE0B;;;EAOE,aAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAjBb,qBAiBa,CAjBS,CAiBT,CAAA,CAAA,EAjBc,aAiBd,CAjB4B,OAiB5B,CAjBoC,CAiBpC,CAAA,CAAA;EAA5B;;;;;EAQA,cAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAjBA,sBAiBA,CAjBuB,CAiBvB,CAAA,EAAA,GAAA,EAAA,MAAA,CAAA,EAfL,qBAeK,CAfiB,QAejB,CAf0B,CAe1B,CAAA,CAAA;EACqB;;;;EAMrB,YAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAfA,2BAeA,CAf4B,CAe5B,CAAA,EAAA,GAAA,EAAA,MAAA,CAAA,EAbL,aAaK,CAbS,aAaT,CAbuB,CAavB,CAAA,CAAA;EAE2B;;;EAOvB,iBAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAhBJ,qBAgBI,CAhBkB,CAgBlB,CAAA,CAAA,EAfT,iBAeS,CAfS,OAeT,CAfiB,CAejB,CAAA,CAAA;EACW;;;EAMsB,gBAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAhBrC,2BAgBqC,CAhBT,CAgBS,CAAA,EAAA,GAAA,EAAA,MAAA,CAAA,EAd1C,iBAc0C,CAdxB,aAcwB,CAdV,CAcU,CAAA,CAAA;EAQhC;;;EAAK,gBAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAfN,CAeM,EAAA,YAAA,CAAA,EAdD,KAcC,CAdK,CAcL,CAAA,CAAA,EAbf,OAae,CAAA,IAAA,CAAA;EACI;;;EACnB,eAAA,CAAA,EAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAV0C,OAU1C,CAAA,IAAA,CAAA;EAGM;;;;;EAKA,MAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAVD,IAUC,CAVI,CAUJ,CAAA,GAVS,kBAUT,CAV4B,CAU5B,CAAA,EAAA,WAAA,CAAA,EATO,KASP,CATa,CASb,CAAA,CAAA,EARN,OAQM,CARE,CAQF,CAAA;EACG;EAAR,IAAA,CAAA,MANK,UAML,EAAA,MANqB,UAMrB,CAAA,CAAA,IAAA,EAAA;IAGK,OAAA,EAAA,MAAA;IAGI,OAAA,EAAA,MAAA;IAEK,SAAA,EAXL,GAWK;IAAT,GAAA,CAAA,EAAA,MAAA;IACG,IAAA,CAAA,EAVH,IAUG,CAVE,GAUF,EAVK,GAUL,CAAA;EAAR,CAAA,CAAA,EATA,OASA,CATQ,GASR,CAAA;EAAO;EAGI,IAAA,CAAA,MATN,UASM,CAAA,CAAkB,IAAA,EAAA;IAWvB,OAAA,EAAA,MAAA;IAEI,OAAA,EAAA,MAAA;IAAN,SAAA,EAnBK,GAmBL;IAEO,GAAA,CAAA,EAAA,MAAA;IAAN,IAAA,CAAA,EAnBA,QAmBA,CAnBS,GAmBT,CAAA;EAgBA,CAAA,CAAA,EAlCL,OAkCK,CAlCG,IAkCH,CAAA;;AAGM,UAlCA,kBAkCkB,CAAA,MAAA,OAAA,EAAA,MAAA,OAAA,CAAA,CAAA;EAA+B;;;;AAOlE;EAYgD,cAAA,CAAA,EAAA,MAAA;EAAG;;;EALnB,OAAA,CAAA,EArCpB,MAqCoB,CAAA,MAAA,EAAA,MAAA,CAAA;EAAtB,KAAA,CAAA,EAnCA,KAmCA,CAnCM,GAmCN,CAAA;EACA,MAAA,CAAA,EAlCC,KAkCD,CAlCO,GAkCP,CAAA;EAAG;;;;;;AAOb;EAegD,OAAA,CAAA,EAAA,MAAA;EAAnB;;;;;EAAmB,MAAA,CAAA,EAxCrC,WAwCqC;;AAAD,UArC9B,kBAqC8B,CAAA,GAAA,CAAA,SArCA,kBAqCA,CArCmB,GAqCnB,EAAA,IAAA,CAAA,CAAA;EAGnC;AAEZ;;EACmB,KAAA,CAAA,EAAA,MAAA,GAvCA,QAuCA;;AAA6B,cApCnC,IAoCmC,CAAA,GAAA,EAAA,GAAA,CAAA,CAAA;EAAI,SAAA,IAAA,EAxBvB,kBAwBuB,CAxBJ,GAwBI,EAxBD,GAwBC,CAAA;EAAE;;;;;EAIE,OAAA,IAAA,CAAA,MAAA,OAAA,EAAA,MAAA,OAAA,CAAA,CAAA,IAAA,EAjC9C,kBAiC8C,CAjC3B,GAiC2B,EAjCxB,GAiCwB,CAAA,CAAA,EAhCnD,IAgCmD,CAhC9C,GAgC8C,EAhC3C,GAgC2C,CAAA;EAAtB,WAAA,CAAA,IAAA,EA5BL,kBA4BK,CA5Bc,GA4Bd,EA5BiB,GA4BjB,CAAA;;AAA+B,cAzBpD,QAyBoD,CAAA,MAAA,OAAA,CAAA,CAAA;EAAW,SAAA,IAAA,EAV/C,kBAU+C,CAV5B,GAU4B,CAAA;EAK3D;;;EACkB,OAAA,IAAA,CAAA,MAAA,OAAA,CAAA,CAAA,IAAA,EA3BK,kBA2BL,CA3BwB,GA2BxB,CAAA,CAAA,EA3B6B,QA2B7B,CA3BsC,GA2BtC,CAAA;EAAwB,KAAA,CAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EAAA,WAAA,CAAA,IAAA,EAhB9B,kBAgB8B,CAhBX,GAgBW,CAAA;;AAEJ,KAf3C,YAe2C,CAAA,GAAA,CAAA,GAfzB,GAeyB,SAAA,CAAA,KAAA,EAAA,EAAA,GAAA,GAAA,EAAA,CAAA,GAfO,CAeP,GAAA,OAAA;AAAnB,KAbxB,aAawB,CAAA,CAAA,CAAA,GAAA,QAAqB,MAZ3C,CAY2C,IAZtC,CAYsC,CAZpC,CAYoC,CAAA,SAAA,KAAA,GAAA,KAAA,GAZT,CAYS,GAZL,CAYK,CAZH,CAYG,CAAA,UAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,IAAA,EAAA,KAAA,EAAA,EAAA,GATlD,WASkD,CAAA,KAAA,EAAA,CAAA,IAAA,CAAA,GAAA,IAAA,EAAA,CAAA,GARrC,CAQqC,EAAA,GAAA,CAAA,IAAA,GARvB,IAQuB,CARlB,YAQkB,CARL,CAQK,CAAA,EARD,CAQC,CAAA,CAAA,CAAA,EAAA,GARQ,WAQR,CARoB,CAQpB,CAAA,GAAA,KAAA,EAAA;AAAA,kBAHxC,GAAA,CAGwC;EAOxC,MAAA,IAAM,EAAA,CAAA,GAAA,EAAA,GAAA,CAAA,CAAA,IASb,EAlByB,kBAkBxB,CAlB2C,GAkB3C,EAlB8C,GAkB9C,CAAA,EAAA,GAlBgD,IAkBhD,CAlBgD,GAkBhD,EAlBgD,GAkBhD,CAAA;EAQC,MAAA,QAAA,EAAA,CAAA,GAAA,CAAA,CAAA,IAAkB,EAxBM,kBAwBN,CAxByB,GAwBzB,CAAA,EAAA,GAxB2B,QAwB3B,CAxB2B,GAwB3B,CAAA;AAuB9B;;;;AAEkD,UA1CjC,MA0CiC,CAAA,GAAA,CAAA,CAAA;EAAI;;;EAK/B,KAAA,EAAA,OAAA;EAAgC;;;EAAlB,MAAA,EAtC3B,GAsC2B;;;;;;AAeoB,KA7C7C,kBA6C6C,CAAA,CAAA,CAAA,GAAA;EAEhC;;;;;EACF,SAAA,YAAA,EAAA,MAAA;EAAR,SAAA,MAAA,EAAA,UAAA,GAAA,oBAAA;EAeK,SAAA,UAAA,EAAA,IAAA;CAAU;;;;;;;;;;;;;AAkBqB,KA1DvC,qBA0DuC,CAAA,CAAA,CAAA,GA1DZ,IA0DY,CAAA,QAAP,MAxD5B,CAwD4B,IAxDvB,CAwDuB,CAxDrB,CAwDqB,CAAA,SAAA,KAAA,GAAA,KAAA,GAxDM,CAwDN,GAxDU,CAwDV,CAxDY,CAwDZ,CAAA,UAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,IAAA,EAAA,KAAA,EAAA,EAAA,GArDnC,WAqDmC,CAAA,KAAA,EAAA,CAAA,IAAA,CAAA,GAAA,IAAA,EAAA,CAAA,GAnDrB,CAmDqB,EAAA,GAAA,CAAA,IAAA,GAnDP,IAmDO,CAnDF,YAmDE,CAnDW,CAmDX,CAAA,EAnDe,CAmDf,CAAA,CAAA,CAAA,EAAA,GAlD/B,WAkD+B,CAlDnB,CAkDmB,CAAA,GAAA,KAAA,EAAR,GAAA;EA1DG;;AAuEvC;AAcA;;;;;;;EAIO,cAAA,EApEa,CAoEb,SApEuB,MAoEvB,CAAA,MAAA,EAAA,OAAA,CAAA,GAnEC,CAmED,CAAA,KAAA,CAAA,UAAA,CAAA,GAAA,EAAA,GAAA,EAAA,GAAA,IAAA,EAAA,KAAA,EAAA,EAAA,GAnEkD,OAmElD,CAAA,KAAA,EAAA,CAAA,IAAA,CAAA,GAAA,IAAA,EAAA,CAAA,GAjEkB,CAiElB,EAAA,GAAA,CAAA,IAAA,GAjEgC,QAiEhC,CAjEyC,YAiEzC,CAjEsD,CAiEtD,CAAA,CAAA,CAAA,CAAA,EAAA,GAhEQ,OAgER,CAhEgB,kBAgEhB,CAhEmC,CAgEnC,CAAA,CAAA,GAAA,KAAA,GAAA,KAAA;EAEc;;;;;;;;AAKrB;;;EA0BsB,cAAA,EAlFF,CAkFE,SAlFQ,MAkFR,CAAA,MAAA,EAAA,OAAA,CAAA,GAjFd,CAiFc,CAAA,KAAA,CAAA,UAAA,CAAA,GAAA,IAAA,EAAA,GAAA,EAAA,GAjFqB,OAiFrB,CAAA,KAAA,EAAA,CAAA,IAAA,CAAA,IAAA,CAAA,EAhFJ,IAgFI,CAAA,IAAA,EAhFO,CAgFP,CAAA,EAAA,GAhFc,OAgFd,CAhFsB,CAgFtB,CAAA,GAAA,KAAA,GAAA,KAAA;EAAiB;;;;;;;;;;kBAlEnB,UAAU,0BACtB,oCAAmC,4BACzB,WAAW,OAAO,QAAQ,OAAO;;;;;;;KAavC;;;;;;;;;;;KAcA,qCACE,KAAK,EAAE,2BAA2B,IAAI,EAAE,4CAG/C,sCAEc,cAAc,SAAS,aAAa,UAC9C,QAAQ,KAAK;KAIZ,cAAA;;;;;;;;;;YAUA;;;;;;;;UASF;;;;;;sBAOY"}
1
+ {"version":3,"file":"api.d.ts","names":[],"sources":["../src/api.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","names":["opts: IngressCallOptions<I, O>","opts: IngressSendOptions<I>"],"sources":["../src/api.ts"],"sourcesContent":["import type {\n Service,\n VirtualObjectDefinitionFrom,\n Workflow,\n VirtualObject,\n ServiceDefinitionFrom,\n WorkflowDefinitionFrom,\n Serde,\n Duration,\n JournalValueCodec,\n} from \"@restatedev/restate-sdk-core\";\nimport { millisOrDurationToMillis } from \"@restatedev/restate-sdk-core\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * A remote client for a Restate service.\n *\n * Use the following client to interact with services defined\n * - `serviceClient` to create a client for a service.\n * - `workflowClient` to create a client for a workflow.\n * - `objectClient` to create a client for a virtual object.\n *\n */\nexport interface Ingress {\n /**\n * Create a client from a {@link ServiceDefinition}.\n */\n serviceClient<D>(opts: ServiceDefinitionFrom<D>): IngressClient<Service<D>>;\n\n /**\n * Create a client from a {@link WorkflowDefinition}.\n *\n * @param key the key of the workflow.\n */\n workflowClient<D>(\n opts: WorkflowDefinitionFrom<D>,\n key: string\n ): IngressWorkflowClient<Workflow<D>>;\n\n /**\n * Create a client from a {@link VirtualObjectDefinition}.\n * @param key the key of the virtual object.\n */\n objectClient<D>(\n opts: VirtualObjectDefinitionFrom<D>,\n key: string\n ): IngressClient<VirtualObject<D>>;\n\n /**\n * Create a client from a {@link ServiceDefinition}.\n */\n serviceSendClient<D>(\n opts: ServiceDefinitionFrom<D>\n ): IngressSendClient<Service<D>>;\n\n /**\n * Create a client from a {@link VirtualObjectDefinition}.\n */\n objectSendClient<D>(\n opts: VirtualObjectDefinitionFrom<D>,\n key: string\n ): IngressSendClient<VirtualObject<D>>;\n\n /**\n * Resolve an awakeable from the ingress client.\n */\n resolveAwakeable<T>(\n id: string,\n payload?: T,\n payloadSerde?: Serde<T>\n ): Promise<void>;\n\n /**\n * Reject an awakeable from the ingress client.\n */\n rejectAwakeable(id: string, reason: string): Promise<void>;\n\n /**\n * Obtain the result of a service that was asynchronously submitted (via a sendClient).\n *\n * @param send either the send response or the workflow submission as obtained by the respective clients.\n */\n result<T>(\n send: Send<T> | WorkflowSubmission<T>,\n resultSerde?: Serde<T>\n ): Promise<T>;\n\n /** Generic request-response call. Routes directly by service name without a typed definition. */\n call<I = Uint8Array, O = Uint8Array>(opts: {\n service: string;\n handler: string;\n parameter: I;\n key?: string;\n opts?: Opts<I, O>;\n }): Promise<O>;\n\n /** Generic fire-and-forget send. Routes directly by service name without a typed definition. */\n send<I = Uint8Array>(opts: {\n service: string;\n handler: string;\n parameter: I;\n key?: string;\n opts?: SendOpts<I>;\n }): Promise<Send>;\n}\n\nexport interface IngressCallOptions<I = unknown, O = unknown> {\n /**\n * Key to use for idempotency key.\n *\n * See https://docs.restate.dev/operate/invocation#invoke-a-handler-idempotently for more details.\n */\n idempotencyKey?: string;\n\n /**\n * Headers to attach to the request.\n */\n headers?: Record<string, string>;\n\n input?: Serde<I>;\n\n output?: Serde<O>;\n\n /**\n * Timeout to be used when executing the request. In milliseconds.\n *\n * Same as {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal#aborting_a_fetch_with_timeout_or_explicit_abort | AbortSignal.timeout()}.\n *\n * This field is exclusive with `signal`, and using both of them will result in a runtime failure.\n */\n timeout?: number;\n\n /**\n * Signal to abort the underlying `fetch` operation. See {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal}.\n *\n * This field is exclusive with `timeout`, and using both of them will result in a runtime failure.\n */\n signal?: AbortSignal;\n}\n\nexport interface IngressSendOptions<I> extends IngressCallOptions<I, void> {\n /**\n * If set, the invocation will be enqueued now to be executed after the provided delay. In milliseconds.\n */\n delay?: number | Duration;\n}\n\nexport class Opts<I, O> {\n /**\n * Create a call configuration from the provided options.\n *\n * @param opts the call configuration\n */\n public static from<I = unknown, O = unknown>(\n opts: IngressCallOptions<I, O>\n ): Opts<I, O> {\n return new Opts(opts);\n }\n\n constructor(readonly opts: IngressCallOptions<I, O>) {}\n}\n\nexport class SendOpts<I = unknown> {\n /**\n * @param opts Create send options\n */\n public static from<I = unknown>(opts: IngressSendOptions<I>): SendOpts<I> {\n return new SendOpts(opts);\n }\n\n delay(): number | undefined {\n if (this.opts.delay !== undefined) {\n return millisOrDurationToMillis(this.opts.delay);\n }\n return undefined;\n }\n\n constructor(readonly opts: IngressSendOptions<I>) {}\n}\n\nexport type InferArgType<P> = P extends [infer A, ...any[]] ? A : unknown;\n\nexport type IngressClient<M> = {\n [K in keyof M as M[K] extends never ? never : K]: M[K] extends (\n arg: any,\n ...args: infer P\n ) => PromiseLike<infer O>\n ? (...args: [...P, ...[opts?: Opts<InferArgType<P>, O>]]) => PromiseLike<O>\n : never;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace rpc {\n export const opts = <I, O>(opts: IngressCallOptions<I, O>) => Opts.from(opts);\n\n export const sendOpts = <I>(opts: IngressSendOptions<I>) =>\n SendOpts.from(opts);\n}\n\n/**\n * Represents the output of a workflow.\n */\nexport interface Output<O> {\n /**\n * Whether the output is ready.\n */\n ready: boolean;\n\n /**\n * The output of the workflow.\n */\n result: O;\n}\n\n/**\n * Represents a successful workflow submission.\n *\n */\n/* eslint-disable-next-line @typescript-eslint/no-unused-vars */\nexport type WorkflowSubmission<T> = {\n /**\n * The invocation id of the workflow. You can use that id to\n * with the introspection tools (restate cli, logging, metrics)\n *\n */\n readonly invocationId: string;\n readonly status: \"Accepted\" | \"PreviouslyAccepted\";\n readonly attachable: true;\n};\n\n/**\n * A client for a workflow.\n *\n * This client represents the workflow definition, with the following additional methods:\n * - `workflowSubmit` to submit the workflow.\n * - `workflowAttach` to attach to the workflow and wait for its completion\n * - `workflowOutput` to check if the workflow's output is ready/available.\n *\n * Once a workflow is submitted, it can be attached to, and the output can be retrieved.\n *\n * @typeParam M the type of the workflow.\n */\nexport type IngressWorkflowClient<M> = Omit<\n {\n [K in keyof M as M[K] extends never ? never : K]: M[K] extends (\n arg: any,\n ...args: infer P\n ) => PromiseLike<infer O>\n ? (\n ...args: [...P, ...[opts?: Opts<InferArgType<P>, O>]]\n ) => PromiseLike<O>\n : never;\n } & {\n /**\n * Submit this workflow.\n *\n * This instructs restate to execute the 'run' handler of the workflow, idempotently.\n * The workflow will be executed asynchronously, and the promise will resolve when the workflow has been accepted.\n * Please note that submitting a workflow does not wait for it to completion, and it is safe to retry the submission,\n * in case of failure.\n *\n * @param argument the same argument type as defined by the 'run' handler.\n */\n workflowSubmit: M extends Record<string, unknown>\n ? M[\"run\"] extends (arg: any, ...args: infer I) => Promise<infer O>\n ? (\n ...args: [...I, ...[opts?: SendOpts<InferArgType<I>>]]\n ) => Promise<WorkflowSubmission<O>>\n : never\n : never;\n\n /**\n * Attach to this workflow.\n *\n * This instructs restate to attach to the workflow and wait for it to complete.\n * It is only possible to 'attach' to a workflow that has been previously submitted.\n * The promise will resolve when the workflow has completed either successfully with a result,\n * or be rejected with an error.\n * This operation is safe to retry many times, and it will always return the same result.\n *\n * @returns a promise that resolves when the workflow has completed.\n */\n workflowAttach: M extends Record<string, unknown>\n ? M[\"run\"] extends (...args: any) => Promise<infer O>\n ? (opts?: Opts<void, O>) => Promise<O>\n : never\n : never;\n\n /**\n * Try retrieving the output of this workflow.\n *\n * This instructs restate to check if the workflow's output is ready/available.\n * The returned Output object will have a 'ready' field set to true if the output is ready.\n * If the output is ready, the 'result' field will contain the output.\n * note: that this operation will not wait for the workflow to complete, to do so use 'workflowAttach'.\n *\n * @returns a promise that resolves if the workflow's output is ready/available.\n */\n workflowOutput: M extends Record<string, unknown>\n ? M[\"run\"] extends (...args: any) => Promise<infer O>\n ? (opts?: Opts<void, O>) => Promise<Output<O>>\n : never\n : never;\n },\n \"run\"\n>;\n\n/**\n * A send response.\n *\n * @typeParam T the type of the response.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport type Send<T = unknown> = {\n /**\n * The invocation id of the send.\n */\n invocationId: string;\n\n /**\n * The status of the send.\n */\n status: \"Accepted\" | \"PreviouslyAccepted\";\n\n attachable: boolean;\n};\n\nexport type IngressSendClient<M> = {\n [K in keyof M as M[K] extends never ? never : K]: M[K] extends (\n arg: any,\n ...args: infer P\n ) => PromiseLike<infer O>\n ? (\n ...args: [...P, ...[opts?: SendOpts<InferArgType<P>>]]\n ) => Promise<Send<O>>\n : never;\n};\n\nexport type ConnectionOpts = {\n /**\n * Restate ingress URL.\n * For example: http://localhost:8080\n */\n url: string;\n /**\n * Headers to attach on every request.\n * Use this to attach authentication headers.\n */\n headers?: Record<string, string>;\n\n /**\n * Default serde to use for ingress payloads when no operation-specific serde\n * is provided. Applies to handler calls, workflow attaches/output polling,\n * awakeable resolution, and attached invocation results.\n *\n * Defaults to `restate.serde.json`.\n */\n serde?: Serde<any>;\n\n /**\n * Codec to use for input/outputs. Check {@link JournalValueCodec} for more details\n *\n * @experimental\n */\n journalValueCodec?: JournalValueCodec;\n};\n"],"mappings":";;;AAoJA,IAAa,OAAb,MAAa,KAAW;;;;;;CAMtB,OAAc,KACZ,MACY;AACZ,SAAO,IAAI,KAAK,KAAK;;CAGvB,YAAY,AAASA,MAAgC;EAAhC;;;AAGvB,IAAa,WAAb,MAAa,SAAsB;;;;CAIjC,OAAc,KAAkB,MAA0C;AACxE,SAAO,IAAI,SAAS,KAAK;;CAG3B,QAA4B;AAC1B,MAAI,KAAK,KAAK,UAAU,OACtB,QAAO,yBAAyB,KAAK,KAAK,MAAM;;CAKpD,YAAY,AAASC,MAA6B;EAA7B;;;;;cAgBM,SAAmC,KAAK,KAAK,KAAK;kBAEjD,SAC1B,SAAS,KAAK,KAAK"}
1
+ {"version":3,"file":"api.js","names":["opts: IngressCallOptions<I, O>","opts: IngressSendOptions<I>"],"sources":["../src/api.ts"],"sourcesContent":["import type {\n Service,\n VirtualObjectDefinitionFrom,\n Workflow,\n VirtualObject,\n ServiceDefinitionFrom,\n WorkflowDefinitionFrom,\n Serde,\n Duration,\n JournalValueCodec,\n} from \"@restatedev/restate-sdk-core\";\nimport { millisOrDurationToMillis } from \"@restatedev/restate-sdk-core\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * A remote client for a Restate service.\n *\n * Use the following client to interact with services defined\n * - `serviceClient` to create a client for a service.\n * - `workflowClient` to create a client for a workflow.\n * - `objectClient` to create a client for a virtual object.\n *\n */\nexport interface Ingress {\n /**\n * Create a client from a {@link ServiceDefinition}.\n */\n serviceClient<D>(opts: ServiceDefinitionFrom<D>): IngressClient<Service<D>>;\n\n /**\n * Create a client from a {@link WorkflowDefinition}.\n *\n * @param key the key of the workflow.\n */\n workflowClient<D>(\n opts: WorkflowDefinitionFrom<D>,\n key: string\n ): IngressWorkflowClient<Workflow<D>>;\n\n /**\n * Create a client from a {@link VirtualObjectDefinition}.\n * @param key the key of the virtual object.\n */\n objectClient<D>(\n opts: VirtualObjectDefinitionFrom<D>,\n key: string\n ): IngressClient<VirtualObject<D>>;\n\n /**\n * Create a client from a {@link ServiceDefinition}.\n */\n serviceSendClient<D>(\n opts: ServiceDefinitionFrom<D>\n ): IngressSendClient<Service<D>>;\n\n /**\n * Create a client from a {@link VirtualObjectDefinition}.\n */\n objectSendClient<D>(\n opts: VirtualObjectDefinitionFrom<D>,\n key: string\n ): IngressSendClient<VirtualObject<D>>;\n\n /**\n * Resolve an awakeable from the ingress client.\n */\n resolveAwakeable<T>(\n id: string,\n payload?: T,\n payloadSerde?: Serde<T>\n ): Promise<void>;\n\n /**\n * Reject an awakeable from the ingress client.\n */\n rejectAwakeable(id: string, reason: string): Promise<void>;\n\n /**\n * Obtain the result of a service that was asynchronously submitted (via a sendClient).\n *\n * @param send either the send response or the workflow submission as obtained by the respective clients.\n */\n result<T>(\n send: Send<T> | WorkflowSubmission<T>,\n resultSerde?: Serde<T>\n ): Promise<T>;\n\n /** Generic request-response call. Routes directly by service name without a typed definition. */\n call<I = Uint8Array, O = Uint8Array>(opts: {\n service: string;\n handler: string;\n parameter: I;\n key?: string;\n /**\n * Route this call within the given scope. See {@link Ingress.scope}.\n *\n * *NOTE:* This API is experimental. To use it you need a restate-server >= 1.7,\n * configured to enable\n * [service protocol v7](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#service-protocol-v7)\n * and [flow control](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#flow-control).\n * For example, start the restate-server with the environment variables\n * `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.\n *\n * @experimental\n */\n scope?: string;\n opts?: Opts<I, O>;\n }): Promise<O>;\n\n /** Generic fire-and-forget send. Routes directly by service name without a typed definition. */\n send<I = Uint8Array>(opts: {\n service: string;\n handler: string;\n parameter: I;\n key?: string;\n /**\n * Route this send within the given scope. See {@link Ingress.scope}.\n *\n * *NOTE:* This API is experimental. To use it you need a restate-server >= 1.7,\n * configured to enable\n * [service protocol v7](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#service-protocol-v7)\n * and [flow control](https://github.com/restatedev/restate/blob/main/release-notes/v1.7.0.md#flow-control).\n * For example, start the restate-server with the environment variables\n * `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.\n *\n * @experimental\n */\n scope?: string;\n opts?: SendOpts<I>;\n }): Promise<Send>;\n\n /**\n * Returns a {@link ScopedIngress} that routes all calls within the given scope.\n *\n * **NOTE:** This API is in preview and is not enabled by default.\n * To use it in restate-server 1.7, enable the flow control and protocol v7 experimental features,\n * via `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.\n * These can be enabled only on **new clusters**, for more info check out https://docs.restate.dev/services/flow-control#enabling-flow-control.\n * If these experimental features aren't enabled, the invocation won't be ingested and the client request fails.\n *\n * A scope is a sub-grouping of resources (invocations, virtual object instances, workflow\n * instances, concurrency limits) within the Restate cluster.\n * It becomes part of the target identity tuple:\n * - `scope, service, handler, idempotencyKey?`\n * - `scope, virtualObject, objectKey, handler, idempotencyKey?`\n * - `scope, workflow, workflowKey, handler`\n *\n * Under the hood, the scope contributes to the partition key, so all resources in a scope get co-located by the restate-server.\n *\n * Omitting the scope (i.e. using the regular `serviceClient` / `workflowClient` methods)\n * is equivalent to calling with no scope, which is the existing behavior.\n *\n * The scope key must consist only of `[a-zA-Z0-9_.-]` characters, with 1 <= length <= 36 chars.\n *\n * @example\n * ```ts\n * // Route a call into a named scope\n * await ingress.scope(\"tenant-123\").serviceClient(MyService).process(payload);\n *\n * // Idempotency keys are scoped — \"req-1\" in \"tenant-123\" is distinct from \"req-1\" in \"tenant-456\"\n * await ingress.scope(\"tenant-123\").serviceClient(MyService)\n * .process(payload, rpc.opts({ idempotencyKey: \"req-1\" }));\n *\n * // Combine with a limit key to enforce per-scope concurrency limits\n * await ingress.scope(\"tenant-123\").workflowClient(MyWorkflow, \"wf-key\")\n * .run(input, rpc.opts({ limitKey: \"api-key/user42\" }));\n * ```\n *\n * @param scopeKey the scope identifier\n * @see https://docs.restate.dev/services/flow-control\n * @experimental\n */\n scope(scopeKey: string): ScopedIngress;\n}\n\n/**\n * An ingress client for making RPC calls within a specific scope.\n *\n * @see {@link Ingress.scope}\n * @experimental\n * @interface\n */\nexport type ScopedIngress = Pick<\n Ingress,\n \"serviceClient\" | \"serviceSendClient\" | \"workflowClient\"\n>;\n\nexport interface IngressCallOptions<I = unknown, O = unknown> {\n /**\n * Key to use for idempotency key.\n *\n * See https://docs.restate.dev/operate/invocation#invoke-a-handler-idempotently for more details.\n */\n idempotencyKey?: string;\n\n /**\n * An optional concurrency limit key within the scope.\n * A limit key can only be used in conjunction with a scope (see {@link Ingress.scope}).\n *\n * **NOTE:** This API is in preview and is not enabled by default.\n * To use it in restate-server 1.7, enable the flow control and protocol v7 experimental features,\n * via `RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true` and `RESTATE_EXPERIMENTAL_ENABLE_VQUEUES=true`.\n * These can be enabled only on **new clusters**, for more info check out https://docs.restate.dev/services/flow-control#enabling-flow-control.\n * If these experimental features aren't enabled, the invocation isn't ingested and the client request fails.\n *\n * The limit key enforces hierarchical concurrency limits on invocations sharing the same scope.\n * It can have one or two levels separated by `/` (e.g. `\"tenant1\"` or `\"tenant1/user42\"`).\n * Each level must consist only of `[a-zA-Z0-9_.-]` characters, and 1 <= length <= 36.\n *\n * The limit key is **not** part of the request identity: two calls to the same target with the\n * same scope and object key but different limit keys refer to the **same** resource instance.\n * The limit key only affects concurrency limits, not resource identity.\n *\n * @experimental\n */\n limitKey?: string;\n\n /**\n * Headers to attach to the request.\n */\n headers?: Record<string, string>;\n\n input?: Serde<I>;\n\n output?: Serde<O>;\n\n /**\n * Timeout to be used when executing the request. In milliseconds.\n *\n * Same as {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal#aborting_a_fetch_with_timeout_or_explicit_abort | AbortSignal.timeout()}.\n *\n * This field is exclusive with `signal`, and using both of them will result in a runtime failure.\n */\n timeout?: number;\n\n /**\n * Signal to abort the underlying `fetch` operation. See {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal}.\n *\n * This field is exclusive with `timeout`, and using both of them will result in a runtime failure.\n */\n signal?: AbortSignal;\n}\n\nexport interface IngressSendOptions<I> extends IngressCallOptions<I, void> {\n /**\n * If set, the invocation will be enqueued now to be executed after the provided delay. In milliseconds.\n */\n delay?: number | Duration;\n}\n\nexport class Opts<I, O> {\n /**\n * Create a call configuration from the provided options.\n *\n * @param opts the call configuration\n */\n public static from<I = unknown, O = unknown>(\n opts: IngressCallOptions<I, O>\n ): Opts<I, O> {\n return new Opts(opts);\n }\n\n constructor(readonly opts: IngressCallOptions<I, O>) {}\n}\n\nexport class SendOpts<I = unknown> {\n /**\n * @param opts Create send options\n */\n public static from<I = unknown>(opts: IngressSendOptions<I>): SendOpts<I> {\n return new SendOpts(opts);\n }\n\n delay(): number | undefined {\n if (this.opts.delay !== undefined) {\n return millisOrDurationToMillis(this.opts.delay);\n }\n return undefined;\n }\n\n constructor(readonly opts: IngressSendOptions<I>) {}\n}\n\nexport type InferArgType<P> = P extends [infer A, ...any[]] ? A : unknown;\n\nexport type IngressClient<M> = {\n [K in keyof M as M[K] extends never ? never : K]: M[K] extends (\n arg: any,\n ...args: infer P\n ) => PromiseLike<infer O>\n ? (...args: [...P, ...[opts?: Opts<InferArgType<P>, O>]]) => PromiseLike<O>\n : never;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace rpc {\n export const opts = <I, O>(opts: IngressCallOptions<I, O>) => Opts.from(opts);\n\n export const sendOpts = <I>(opts: IngressSendOptions<I>) =>\n SendOpts.from(opts);\n}\n\n/**\n * Represents the output of a workflow.\n */\nexport interface Output<O> {\n /**\n * Whether the output is ready.\n */\n ready: boolean;\n\n /**\n * The output of the workflow.\n */\n result: O;\n}\n\n/**\n * Represents a successful workflow submission.\n *\n */\n/* eslint-disable-next-line @typescript-eslint/no-unused-vars */\nexport type WorkflowSubmission<T> = {\n /**\n * The invocation id of the workflow. You can use that id to\n * with the introspection tools (restate cli, logging, metrics)\n *\n */\n readonly invocationId: string;\n readonly status: \"Accepted\" | \"PreviouslyAccepted\";\n readonly attachable: true;\n};\n\n/**\n * A client for a workflow.\n *\n * This client represents the workflow definition, with the following additional methods:\n * - `workflowSubmit` to submit the workflow.\n * - `workflowAttach` to attach to the workflow and wait for its completion\n * - `workflowOutput` to check if the workflow's output is ready/available.\n *\n * Once a workflow is submitted, it can be attached to, and the output can be retrieved.\n *\n * @typeParam M the type of the workflow.\n */\nexport type IngressWorkflowClient<M> = Omit<\n {\n [K in keyof M as M[K] extends never ? never : K]: M[K] extends (\n arg: any,\n ...args: infer P\n ) => PromiseLike<infer O>\n ? (\n ...args: [...P, ...[opts?: Opts<InferArgType<P>, O>]]\n ) => PromiseLike<O>\n : never;\n } & {\n /**\n * Submit this workflow.\n *\n * This instructs restate to execute the 'run' handler of the workflow, idempotently.\n * The workflow will be executed asynchronously, and the promise will resolve when the workflow has been accepted.\n * Please note that submitting a workflow does not wait for it to completion, and it is safe to retry the submission,\n * in case of failure.\n *\n * @param argument the same argument type as defined by the 'run' handler.\n */\n workflowSubmit: M extends Record<string, unknown>\n ? M[\"run\"] extends (arg: any, ...args: infer I) => Promise<infer O>\n ? (\n ...args: [...I, ...[opts?: SendOpts<InferArgType<I>>]]\n ) => Promise<WorkflowSubmission<O>>\n : never\n : never;\n\n /**\n * Attach to this workflow.\n *\n * This instructs restate to attach to the workflow and wait for it to complete.\n * It is only possible to 'attach' to a workflow that has been previously submitted.\n * The promise will resolve when the workflow has completed either successfully with a result,\n * or be rejected with an error.\n * This operation is safe to retry many times, and it will always return the same result.\n *\n * @returns a promise that resolves when the workflow has completed.\n */\n workflowAttach: M extends Record<string, unknown>\n ? M[\"run\"] extends (...args: any) => Promise<infer O>\n ? (opts?: Opts<void, O>) => Promise<O>\n : never\n : never;\n\n /**\n * Try retrieving the output of this workflow.\n *\n * This instructs restate to check if the workflow's output is ready/available.\n * The returned Output object will have a 'ready' field set to true if the output is ready.\n * If the output is ready, the 'result' field will contain the output.\n * note: that this operation will not wait for the workflow to complete, to do so use 'workflowAttach'.\n *\n * @returns a promise that resolves if the workflow's output is ready/available.\n */\n workflowOutput: M extends Record<string, unknown>\n ? M[\"run\"] extends (...args: any) => Promise<infer O>\n ? (opts?: Opts<void, O>) => Promise<Output<O>>\n : never\n : never;\n },\n \"run\"\n>;\n\n/**\n * A send response.\n *\n * @typeParam T the type of the response.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport type Send<T = unknown> = {\n /**\n * The invocation id of the send.\n */\n invocationId: string;\n\n /**\n * The status of the send.\n */\n status: \"Accepted\" | \"PreviouslyAccepted\";\n\n attachable: boolean;\n};\n\nexport type IngressSendClient<M> = {\n [K in keyof M as M[K] extends never ? never : K]: M[K] extends (\n arg: any,\n ...args: infer P\n ) => PromiseLike<infer O>\n ? (\n ...args: [...P, ...[opts?: SendOpts<InferArgType<P>>]]\n ) => Promise<Send<O>>\n : never;\n};\n\nexport type ConnectionOpts = {\n /**\n * Restate ingress URL.\n * For example: http://localhost:8080\n */\n url: string;\n /**\n * Headers to attach on every request.\n * Use this to attach authentication headers.\n */\n headers?: Record<string, string>;\n\n /**\n * Default serde to use for ingress payloads when no operation-specific serde\n * is provided. Applies to handler calls, workflow attaches/output polling,\n * awakeable resolution, and attached invocation results.\n *\n * Defaults to `restate.serde.json`.\n */\n serde?: Serde<any>;\n\n /**\n * Codec to use for input/outputs. Check {@link JournalValueCodec} for more details\n *\n * @experimental\n */\n journalValueCodec?: JournalValueCodec;\n};\n"],"mappings":";;;AA2PA,IAAa,OAAb,MAAa,KAAW;;;;;;CAMtB,OAAc,KACZ,MACY;AACZ,SAAO,IAAI,KAAK,KAAK;;CAGvB,YAAY,AAASA,MAAgC;EAAhC;;;AAGvB,IAAa,WAAb,MAAa,SAAsB;;;;CAIjC,OAAc,KAAkB,MAA0C;AACxE,SAAO,IAAI,SAAS,KAAK;;CAG3B,QAA4B;AAC1B,MAAI,KAAK,KAAK,UAAU,OACtB,QAAO,yBAAyB,KAAK,KAAK,MAAM;;CAKpD,YAAY,AAASC,MAA6B;EAA7B;;;;;cAgBM,SAAmC,KAAK,KAAK,KAAK;kBAEjD,SAC1B,SAAS,KAAK,KAAK"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { ConnectionOpts, InferArgType, Ingress, IngressCallOptions, IngressClient, IngressSendClient, IngressSendOptions, IngressWorkflowClient, Opts, Output, Send, SendOpts, WorkflowSubmission, rpc } from "./api.cjs";
1
+ import { ConnectionOpts, InferArgType, Ingress, IngressCallOptions, IngressClient, IngressSendClient, IngressSendOptions, IngressWorkflowClient, Opts, Output, ScopedIngress, Send, SendOpts, WorkflowSubmission, rpc } from "./api.cjs";
2
2
  import { HttpCallError, connect } from "./ingress.cjs";
3
3
  import { Duration, JournalValueCodec, Serde, Service, ServiceDefinition, ServiceDefinitionFrom, VirtualObject, VirtualObjectDefinition, VirtualObjectDefinitionFrom, Workflow, WorkflowDefinition, WorkflowDefinitionFrom, serde } from "@restatedev/restate-sdk-core";
4
- export { type ConnectionOpts, type Duration, HttpCallError, type InferArgType, type Ingress, type IngressCallOptions, type IngressClient, type IngressSendClient, type IngressSendOptions, type IngressWorkflowClient, type JournalValueCodec, Opts, type Output, type Send, SendOpts, type Serde, type Service, type ServiceDefinition, type ServiceDefinitionFrom, type VirtualObject, type VirtualObjectDefinition, type VirtualObjectDefinitionFrom, type Workflow, type WorkflowDefinition, type WorkflowDefinitionFrom, type WorkflowSubmission, connect, rpc, serde };
4
+ export { type ConnectionOpts, type Duration, HttpCallError, type InferArgType, type Ingress, type IngressCallOptions, type IngressClient, type IngressSendClient, type IngressSendOptions, type IngressWorkflowClient, type JournalValueCodec, Opts, type Output, type ScopedIngress, type Send, SendOpts, type Serde, type Service, type ServiceDefinition, type ServiceDefinitionFrom, type VirtualObject, type VirtualObjectDefinition, type VirtualObjectDefinitionFrom, type Workflow, type WorkflowDefinition, type WorkflowDefinitionFrom, type WorkflowSubmission, connect, rpc, serde };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ConnectionOpts, InferArgType, Ingress, IngressCallOptions, IngressClient, IngressSendClient, IngressSendOptions, IngressWorkflowClient, Opts, Output, Send, SendOpts, WorkflowSubmission, rpc } from "./api.js";
1
+ import { ConnectionOpts, InferArgType, Ingress, IngressCallOptions, IngressClient, IngressSendClient, IngressSendOptions, IngressWorkflowClient, Opts, Output, ScopedIngress, Send, SendOpts, WorkflowSubmission, rpc } from "./api.js";
2
2
  import { HttpCallError, connect } from "./ingress.js";
3
3
  import { Duration, JournalValueCodec, Serde, Service, ServiceDefinition, ServiceDefinitionFrom, VirtualObject, VirtualObjectDefinition, VirtualObjectDefinitionFrom, Workflow, WorkflowDefinition, WorkflowDefinitionFrom, serde } from "@restatedev/restate-sdk-core";
4
- export { type ConnectionOpts, type Duration, HttpCallError, type InferArgType, type Ingress, type IngressCallOptions, type IngressClient, type IngressSendClient, type IngressSendOptions, type IngressWorkflowClient, type JournalValueCodec, Opts, type Output, type Send, SendOpts, type Serde, type Service, type ServiceDefinition, type ServiceDefinitionFrom, type VirtualObject, type VirtualObjectDefinition, type VirtualObjectDefinitionFrom, type Workflow, type WorkflowDefinition, type WorkflowDefinitionFrom, type WorkflowSubmission, connect, rpc, serde };
4
+ export { type ConnectionOpts, type Duration, HttpCallError, type InferArgType, type Ingress, type IngressCallOptions, type IngressClient, type IngressSendClient, type IngressSendOptions, type IngressWorkflowClient, type JournalValueCodec, Opts, type Output, type ScopedIngress, type Send, SendOpts, type Serde, type Service, type ServiceDefinition, type ServiceDefinitionFrom, type VirtualObject, type VirtualObjectDefinition, type VirtualObjectDefinitionFrom, type Workflow, type WorkflowDefinition, type WorkflowDefinitionFrom, type WorkflowSubmission, connect, rpc, serde };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACtB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAErD,YAAY,EACV,OAAO,EACP,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,IAAI,EACJ,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,MAAM,GACP,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,YAAY,EACV,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACtB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAErD,YAAY,EACV,OAAO,EACP,aAAa,EACb,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,IAAI,EACJ,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,MAAM,GACP,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAerD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAgBrD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
package/dist/ingress.cjs CHANGED
@@ -45,20 +45,34 @@ function optsFromArgs(args) {
45
45
  };
46
46
  }
47
47
  const IDEMPOTENCY_KEY_HEADER = "idempotency-key";
48
+ const LIMIT_KEY_HEADER = "x-restate-limit-key";
48
49
  const doComponentInvocation = async (opts, params) => {
49
50
  let attachable = false;
50
- const fragments = [];
51
- fragments.push(opts.url);
52
- fragments.push(params.component);
53
- if (params.key) {
54
- const key = encodeURIComponent(params.key);
55
- fragments.push(key);
51
+ let url;
52
+ if (params.scope) {
53
+ const pathType = params.send ? "send" : "call";
54
+ const parts = [
55
+ opts.url,
56
+ "restate/scope",
57
+ encodeURIComponent(params.scope),
58
+ pathType,
59
+ params.component
60
+ ];
61
+ if (params.key) parts.push(encodeURIComponent(params.key));
62
+ parts.push(params.handler);
63
+ url = parts.join("/");
64
+ if (params.send && params.opts instanceof require_api.SendOpts) {
65
+ const delay = params.opts.delay();
66
+ if (delay) url += `?delay=${delay}ms`;
67
+ }
68
+ } else {
69
+ const fragments = [opts.url, params.component];
70
+ if (params.key) fragments.push(encodeURIComponent(params.key));
71
+ fragments.push(params.handler);
72
+ if (params.send ?? false) if (params.opts instanceof require_api.SendOpts) fragments.push(computeDelayAsIso(params.opts));
73
+ else fragments.push("send");
74
+ url = fragments.join("/");
56
75
  }
57
- fragments.push(params.handler);
58
- if (params.send ?? false) if (params.opts instanceof require_api.SendOpts) {
59
- const sendString = computeDelayAsIso(params.opts);
60
- fragments.push(sendString);
61
- } else fragments.push("send");
62
76
  const inputSerde = params.opts?.opts.input ?? opts.serde ?? __restatedev_restate_sdk_core.serde.json;
63
77
  const { body, contentType } = serializeBodyWithContentType(params.parameter, inputSerde, opts.journalValueCodec);
64
78
  const headers = {
@@ -71,11 +85,12 @@ const doComponentInvocation = async (opts, params) => {
71
85
  headers[IDEMPOTENCY_KEY_HEADER] = idempotencyKey;
72
86
  attachable = true;
73
87
  }
88
+ const limitKey = params.opts?.opts.limitKey;
89
+ if (limitKey) headers[LIMIT_KEY_HEADER] = limitKey;
74
90
  let signal;
75
91
  if (params.opts?.opts.signal !== void 0 && params.opts?.opts.timeout !== void 0) throw new Error("You can't specify both signal and timeout options at the same time");
76
92
  else if (params.opts?.opts.signal !== void 0) signal = params.opts?.opts.signal;
77
93
  else if (params.opts?.opts.timeout !== void 0) signal = AbortSignal.timeout(params.opts?.opts.timeout);
78
- const url = fragments.join("/");
79
94
  const httpResponse = await fetch(url, {
80
95
  method: params.method ?? "POST",
81
96
  headers,
@@ -202,11 +217,88 @@ var HttpIngress = class {
202
217
  serviceSendClient(opts) {
203
218
  return this.proxy(opts.name, void 0, true);
204
219
  }
220
+ scope(scopeKey) {
221
+ const conn = this.opts;
222
+ const scopedProxy = (component, key, send) => new Proxy({}, { get: (_target, prop) => {
223
+ const handler = prop;
224
+ return (...args) => {
225
+ const { parameter, opts } = optsFromArgs(args);
226
+ return doComponentInvocation(conn, {
227
+ component,
228
+ handler,
229
+ key,
230
+ parameter,
231
+ opts,
232
+ send,
233
+ scope: scopeKey
234
+ });
235
+ };
236
+ } });
237
+ return {
238
+ serviceClient: (opts) => scopedProxy(opts.name),
239
+ serviceSendClient: (opts) => scopedProxy(opts.name, void 0, true),
240
+ workflowClient: (opts, key) => {
241
+ const component = opts.name;
242
+ const workflowSubmit = async (...args) => {
243
+ const { parameter, opts: opts$1 } = optsFromArgs(args);
244
+ const res = await doComponentInvocation(conn, {
245
+ component,
246
+ handler: "run",
247
+ key,
248
+ send: true,
249
+ parameter,
250
+ opts: opts$1,
251
+ scope: scopeKey
252
+ });
253
+ return {
254
+ invocationId: res.invocationId,
255
+ status: res.status,
256
+ attachable: true
257
+ };
258
+ };
259
+ const workflowAttach = (opts$1) => doWorkflowHandleCall(conn, component, key, "attach", opts$1);
260
+ const workflowOutput = async (opts$1) => {
261
+ try {
262
+ return {
263
+ ready: true,
264
+ result: await doWorkflowHandleCall(conn, component, key, "output", opts$1)
265
+ };
266
+ } catch (e) {
267
+ if (!(e instanceof HttpCallError) || e.status !== 470) throw e;
268
+ return {
269
+ ready: false,
270
+ get result() {
271
+ throw new Error("Calling result() on a non ready workflow");
272
+ }
273
+ };
274
+ }
275
+ };
276
+ return new Proxy({}, { get: (_target, prop) => {
277
+ const handler = prop;
278
+ if (handler === "workflowSubmit") return workflowSubmit;
279
+ else if (handler === "workflowAttach") return workflowAttach;
280
+ else if (handler === "workflowOutput") return workflowOutput;
281
+ return (...args) => {
282
+ const { parameter, opts: opts$1 } = optsFromArgs(args);
283
+ return doComponentInvocation(conn, {
284
+ component,
285
+ handler,
286
+ key,
287
+ parameter,
288
+ opts: opts$1,
289
+ scope: scopeKey
290
+ });
291
+ };
292
+ } });
293
+ }
294
+ };
295
+ }
205
296
  async call(opts) {
206
297
  return doComponentInvocation(this.opts, {
207
298
  component: opts.service,
208
299
  handler: opts.handler,
209
300
  key: opts.key,
301
+ scope: opts.scope,
210
302
  parameter: opts.parameter,
211
303
  send: false,
212
304
  opts: opts.opts
@@ -217,6 +309,7 @@ var HttpIngress = class {
217
309
  component: opts.service,
218
310
  handler: opts.handler,
219
311
  key: opts.key,
312
+ scope: opts.scope,
220
313
  parameter: opts.parameter,
221
314
  send: true,
222
315
  opts: opts.opts
@@ -1 +1 @@
1
- {"version":3,"file":"ingress.d.cts","names":[],"sources":["../src/ingress.ts"],"sourcesContent":[],"mappings":";;;;;;AAyCA;AAIA;;;iBAJgB,OAAA,OAAc,iBAAiB;cAIlC,aAAA,SAAsB,KAAA"}
1
+ {"version":3,"file":"ingress.d.cts","names":[],"sources":["../src/ingress.ts"],"sourcesContent":[],"mappings":";;;;;;AA0CA;AAIA;;;iBAJgB,OAAA,OAAc,iBAAiB;cAIlC,aAAA,SAAsB,KAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"ingress.d.ts","names":[],"sources":["../src/ingress.ts"],"sourcesContent":[],"mappings":";;;;;;AAyCA;AAIA;;;iBAJgB,OAAA,OAAc,iBAAiB;cAIlC,aAAA,SAAsB,KAAA"}
1
+ {"version":3,"file":"ingress.d.ts","names":[],"sources":["../src/ingress.ts"],"sourcesContent":[],"mappings":";;;;;;AA0CA;AAIA;;;iBAJgB,OAAA,OAAc,iBAAiB;cAIlC,aAAA,SAAsB,KAAA"}
package/dist/ingress.js CHANGED
@@ -43,20 +43,34 @@ function optsFromArgs(args) {
43
43
  };
44
44
  }
45
45
  const IDEMPOTENCY_KEY_HEADER = "idempotency-key";
46
+ const LIMIT_KEY_HEADER = "x-restate-limit-key";
46
47
  const doComponentInvocation = async (opts, params) => {
47
48
  let attachable = false;
48
- const fragments = [];
49
- fragments.push(opts.url);
50
- fragments.push(params.component);
51
- if (params.key) {
52
- const key = encodeURIComponent(params.key);
53
- fragments.push(key);
49
+ let url;
50
+ if (params.scope) {
51
+ const pathType = params.send ? "send" : "call";
52
+ const parts = [
53
+ opts.url,
54
+ "restate/scope",
55
+ encodeURIComponent(params.scope),
56
+ pathType,
57
+ params.component
58
+ ];
59
+ if (params.key) parts.push(encodeURIComponent(params.key));
60
+ parts.push(params.handler);
61
+ url = parts.join("/");
62
+ if (params.send && params.opts instanceof SendOpts) {
63
+ const delay = params.opts.delay();
64
+ if (delay) url += `?delay=${delay}ms`;
65
+ }
66
+ } else {
67
+ const fragments = [opts.url, params.component];
68
+ if (params.key) fragments.push(encodeURIComponent(params.key));
69
+ fragments.push(params.handler);
70
+ if (params.send ?? false) if (params.opts instanceof SendOpts) fragments.push(computeDelayAsIso(params.opts));
71
+ else fragments.push("send");
72
+ url = fragments.join("/");
54
73
  }
55
- fragments.push(params.handler);
56
- if (params.send ?? false) if (params.opts instanceof SendOpts) {
57
- const sendString = computeDelayAsIso(params.opts);
58
- fragments.push(sendString);
59
- } else fragments.push("send");
60
74
  const inputSerde = params.opts?.opts.input ?? opts.serde ?? serde.json;
61
75
  const { body, contentType } = serializeBodyWithContentType(params.parameter, inputSerde, opts.journalValueCodec);
62
76
  const headers = {
@@ -69,11 +83,12 @@ const doComponentInvocation = async (opts, params) => {
69
83
  headers[IDEMPOTENCY_KEY_HEADER] = idempotencyKey;
70
84
  attachable = true;
71
85
  }
86
+ const limitKey = params.opts?.opts.limitKey;
87
+ if (limitKey) headers[LIMIT_KEY_HEADER] = limitKey;
72
88
  let signal;
73
89
  if (params.opts?.opts.signal !== void 0 && params.opts?.opts.timeout !== void 0) throw new Error("You can't specify both signal and timeout options at the same time");
74
90
  else if (params.opts?.opts.signal !== void 0) signal = params.opts?.opts.signal;
75
91
  else if (params.opts?.opts.timeout !== void 0) signal = AbortSignal.timeout(params.opts?.opts.timeout);
76
- const url = fragments.join("/");
77
92
  const httpResponse = await fetch(url, {
78
93
  method: params.method ?? "POST",
79
94
  headers,
@@ -200,11 +215,88 @@ var HttpIngress = class {
200
215
  serviceSendClient(opts) {
201
216
  return this.proxy(opts.name, void 0, true);
202
217
  }
218
+ scope(scopeKey) {
219
+ const conn = this.opts;
220
+ const scopedProxy = (component, key, send) => new Proxy({}, { get: (_target, prop) => {
221
+ const handler = prop;
222
+ return (...args) => {
223
+ const { parameter, opts } = optsFromArgs(args);
224
+ return doComponentInvocation(conn, {
225
+ component,
226
+ handler,
227
+ key,
228
+ parameter,
229
+ opts,
230
+ send,
231
+ scope: scopeKey
232
+ });
233
+ };
234
+ } });
235
+ return {
236
+ serviceClient: (opts) => scopedProxy(opts.name),
237
+ serviceSendClient: (opts) => scopedProxy(opts.name, void 0, true),
238
+ workflowClient: (opts, key) => {
239
+ const component = opts.name;
240
+ const workflowSubmit = async (...args) => {
241
+ const { parameter, opts: opts$1 } = optsFromArgs(args);
242
+ const res = await doComponentInvocation(conn, {
243
+ component,
244
+ handler: "run",
245
+ key,
246
+ send: true,
247
+ parameter,
248
+ opts: opts$1,
249
+ scope: scopeKey
250
+ });
251
+ return {
252
+ invocationId: res.invocationId,
253
+ status: res.status,
254
+ attachable: true
255
+ };
256
+ };
257
+ const workflowAttach = (opts$1) => doWorkflowHandleCall(conn, component, key, "attach", opts$1);
258
+ const workflowOutput = async (opts$1) => {
259
+ try {
260
+ return {
261
+ ready: true,
262
+ result: await doWorkflowHandleCall(conn, component, key, "output", opts$1)
263
+ };
264
+ } catch (e) {
265
+ if (!(e instanceof HttpCallError) || e.status !== 470) throw e;
266
+ return {
267
+ ready: false,
268
+ get result() {
269
+ throw new Error("Calling result() on a non ready workflow");
270
+ }
271
+ };
272
+ }
273
+ };
274
+ return new Proxy({}, { get: (_target, prop) => {
275
+ const handler = prop;
276
+ if (handler === "workflowSubmit") return workflowSubmit;
277
+ else if (handler === "workflowAttach") return workflowAttach;
278
+ else if (handler === "workflowOutput") return workflowOutput;
279
+ return (...args) => {
280
+ const { parameter, opts: opts$1 } = optsFromArgs(args);
281
+ return doComponentInvocation(conn, {
282
+ component,
283
+ handler,
284
+ key,
285
+ parameter,
286
+ opts: opts$1,
287
+ scope: scopeKey
288
+ });
289
+ };
290
+ } });
291
+ }
292
+ };
293
+ }
203
294
  async call(opts) {
204
295
  return doComponentInvocation(this.opts, {
205
296
  component: opts.service,
206
297
  handler: opts.handler,
207
298
  key: opts.key,
299
+ scope: opts.scope,
208
300
  parameter: opts.parameter,
209
301
  send: false,
210
302
  opts: opts.opts
@@ -215,6 +307,7 @@ var HttpIngress = class {
215
307
  component: opts.service,
216
308
  handler: opts.handler,
217
309
  key: opts.key,
310
+ scope: opts.scope,
218
311
  parameter: opts.parameter,
219
312
  send: true,
220
313
  opts: opts.opts
@@ -1 +1 @@
1
- {"version":3,"file":"ingress.js","names":["status: number","responseText: string","message: string","parameter: unknown","opts: Opts<unknown, unknown> | SendOpts<unknown> | undefined","signal: AbortSignal | undefined","body","opts: ConnectionOpts","res: Send","opts","serde"],"sources":["../src/ingress.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport {\n type Service,\n type ServiceDefinitionFrom,\n type VirtualObject,\n type WorkflowDefinitionFrom,\n type Workflow,\n type VirtualObjectDefinitionFrom,\n type Serde,\n serde,\n type JournalValueCodec,\n} from \"@restatedev/restate-sdk-core\";\nimport {\n ConnectionOpts,\n Ingress,\n IngressClient,\n IngressSendClient,\n IngressWorkflowClient,\n Output,\n Send,\n WorkflowSubmission,\n} from \"./api.js\";\n\nimport { Opts, SendOpts } from \"./api.js\";\n\n/**\n * Connect to the restate Ingress\n *\n * @param opts connection options\n * @returns a connection the the restate ingress\n */\nexport function connect(opts: ConnectionOpts): Ingress {\n return new HttpIngress(opts);\n}\n\nexport class HttpCallError extends Error {\n constructor(\n public readonly status: number,\n public readonly responseText: string,\n public override readonly message: string\n ) {\n super(message);\n }\n}\n\ntype InvocationParameters<I> = {\n component: string;\n handler: string;\n key?: string;\n send?: boolean;\n opts?: Opts<I, unknown> | SendOpts<I>;\n parameter?: I;\n method?: string;\n};\n\nfunction optsFromArgs(args: unknown[]): {\n parameter?: unknown;\n opts?: Opts<unknown, unknown> | SendOpts<unknown>;\n} {\n let parameter: unknown;\n let opts: Opts<unknown, unknown> | SendOpts<unknown> | undefined;\n switch (args.length) {\n case 0: {\n break;\n }\n case 1: {\n if (args[0] instanceof Opts) {\n opts = args[0];\n } else if (args[0] instanceof SendOpts) {\n opts = args[0];\n } else {\n parameter = args[0];\n }\n break;\n }\n case 2: {\n parameter = args[0];\n if (args[1] instanceof Opts) {\n opts = args[1];\n } else if (args[1] instanceof SendOpts) {\n opts = args[1];\n } else {\n throw new TypeError(\n \"The second argument must be either Opts or SendOpts\"\n );\n }\n break;\n }\n default: {\n throw new TypeError(\"unexpected number of arguments\");\n }\n }\n return {\n parameter,\n opts,\n };\n}\n\nconst IDEMPOTENCY_KEY_HEADER = \"idempotency-key\";\n\nconst doComponentInvocation = async <I, O>(\n opts: ConnectionOpts,\n params: InvocationParameters<I>\n): Promise<O> => {\n let attachable = false;\n const fragments = [];\n //\n // ingress URL\n //\n fragments.push(opts.url);\n //\n // component\n //\n fragments.push(params.component);\n //\n // has key?\n //\n if (params.key) {\n const key = encodeURIComponent(params.key);\n fragments.push(key);\n }\n //\n // handler\n //\n fragments.push(params.handler);\n if (params.send ?? false) {\n if (params.opts instanceof SendOpts) {\n const sendString = computeDelayAsIso(params.opts);\n fragments.push(sendString);\n } else {\n fragments.push(\"send\");\n }\n }\n //\n // request body\n //\n const inputSerde = params.opts?.opts.input ?? opts.serde ?? serde.json;\n\n const { body, contentType } = serializeBodyWithContentType(\n params.parameter,\n inputSerde,\n opts.journalValueCodec\n );\n //\n // headers\n //\n const headers = {\n ...(opts.headers ?? {}),\n ...(params.opts?.opts?.headers ?? {}),\n };\n if (contentType) {\n headers[\"Content-Type\"] = contentType;\n }\n //\n //idempotency\n //\n const idempotencyKey = params.opts?.opts.idempotencyKey;\n if (idempotencyKey) {\n headers[IDEMPOTENCY_KEY_HEADER] = idempotencyKey;\n attachable = true;\n }\n\n // Abort signal, if any\n let signal: AbortSignal | undefined;\n if (\n params.opts?.opts.signal !== undefined &&\n params.opts?.opts.timeout !== undefined\n ) {\n throw new Error(\n \"You can't specify both signal and timeout options at the same time\"\n );\n } else if (params.opts?.opts.signal !== undefined) {\n signal = params.opts?.opts.signal;\n } else if (params.opts?.opts.timeout !== undefined) {\n signal = AbortSignal.timeout(params.opts?.opts.timeout);\n }\n\n //\n // make the call\n //\n const url = fragments.join(\"/\");\n const httpResponse = await fetch(url, {\n method: params.method ?? \"POST\",\n headers,\n body,\n signal,\n });\n if (!httpResponse.ok) {\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n }\n const responseBuf = new Uint8Array(await httpResponse.arrayBuffer());\n if (!params.send) {\n const decodedBuf = opts.journalValueCodec\n ? await opts.journalValueCodec.decode(responseBuf)\n : responseBuf;\n const outputSerde = params.opts?.opts.output ?? opts.serde ?? serde.json;\n return outputSerde.deserialize(decodedBuf) as O;\n }\n const json = serde.json.deserialize(responseBuf) as O;\n return { ...json, attachable };\n};\n\nconst doWorkflowHandleCall = async <O>(\n opts: ConnectionOpts,\n wfName: string,\n wfKey: string,\n op: \"output\" | \"attach\",\n callOpts?: Opts<unknown, O> | SendOpts<unknown>\n): Promise<O> => {\n const outputSerde = callOpts?.opts.output ?? opts.serde ?? serde.json;\n //\n // headers\n //\n const headers = {\n ...(opts.headers ?? {}),\n };\n //\n // make the call\n //\n const url = `${opts.url}/restate/workflow/${wfName}/${encodeURIComponent(\n wfKey\n )}/${op}`;\n\n // Abort signal, if any\n let signal: AbortSignal | undefined;\n if (\n callOpts?.opts?.signal !== undefined &&\n callOpts?.opts?.timeout !== undefined\n ) {\n throw new Error(\n \"You can't specify both signal and timeout options at the same time\"\n );\n } else if (callOpts?.opts?.signal !== undefined) {\n signal = callOpts?.opts?.signal;\n } else if (callOpts?.opts?.timeout !== undefined) {\n signal = AbortSignal.timeout(callOpts?.opts?.timeout);\n }\n\n const httpResponse = await fetch(url, {\n method: \"GET\",\n headers,\n signal,\n });\n if (httpResponse.ok) {\n const responseBuf = new Uint8Array(await httpResponse.arrayBuffer());\n const decodedBuf = opts.journalValueCodec\n ? await opts.journalValueCodec.decode(responseBuf)\n : responseBuf;\n return outputSerde.deserialize(decodedBuf) as O;\n }\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n};\n\nclass HttpIngress implements Ingress {\n constructor(private readonly opts: ConnectionOpts) {}\n\n private proxy(component: string, key?: string, send?: boolean) {\n return new Proxy(\n {},\n {\n get: (_target, prop) => {\n const handler = prop as string;\n return (...args: unknown[]) => {\n const { parameter, opts } = optsFromArgs(args);\n return doComponentInvocation<unknown, unknown>(this.opts, {\n component,\n handler,\n key,\n parameter,\n opts,\n send,\n });\n };\n },\n }\n );\n }\n\n serviceClient<D>(opts: ServiceDefinitionFrom<D>): IngressClient<Service<D>> {\n return this.proxy(opts.name) as IngressClient<Service<D>>;\n }\n\n objectClient<D>(\n opts: VirtualObjectDefinitionFrom<D>,\n key: string\n ): IngressClient<VirtualObject<D>> {\n return this.proxy(opts.name, key) as IngressClient<VirtualObject<D>>;\n }\n\n workflowClient<D>(\n opts: WorkflowDefinitionFrom<D>,\n key: string\n ): IngressWorkflowClient<Workflow<D>> {\n const component = opts.name;\n const conn = this.opts;\n\n const workflowSubmit = async (\n ...args: unknown[]\n ): Promise<WorkflowSubmission<unknown>> => {\n const { parameter, opts } = optsFromArgs(args);\n const res: Send = await doComponentInvocation(conn, {\n component,\n handler: \"run\",\n key,\n send: true,\n parameter,\n opts,\n });\n\n return {\n invocationId: res.invocationId,\n status: res.status,\n attachable: true,\n };\n };\n\n const workflowAttach = (opts?: Opts<void, unknown>) =>\n doWorkflowHandleCall(conn, component, key, \"attach\", opts);\n\n const workflowOutput = async (\n opts?: Opts<void, unknown>\n ): Promise<Output<unknown>> => {\n try {\n const result = await doWorkflowHandleCall(\n conn,\n component,\n key,\n \"output\",\n opts\n );\n\n return {\n ready: true,\n result,\n };\n } catch (e) {\n if (!(e instanceof HttpCallError) || e.status !== 470) {\n throw e;\n }\n return {\n ready: false,\n get result() {\n throw new Error(\"Calling result() on a non ready workflow\");\n },\n };\n }\n };\n\n return new Proxy(\n {},\n {\n get: (_target, prop) => {\n const handler = prop as string;\n if (handler === \"workflowSubmit\") {\n return workflowSubmit;\n } else if (handler === \"workflowAttach\") {\n return workflowAttach;\n } else if (handler === \"workflowOutput\") {\n return workflowOutput;\n }\n // shared handlers pass trough via the ingress's normal invocation form\n // i.e. POST /<svc>/<key>/<handler>\n return (...args: unknown[]) => {\n const { parameter, opts } = optsFromArgs(args);\n return doComponentInvocation(conn, {\n component,\n handler,\n key,\n parameter,\n opts,\n });\n };\n },\n }\n ) as IngressWorkflowClient<Workflow<D>>;\n }\n\n objectSendClient<D>(\n opts: VirtualObjectDefinitionFrom<D>,\n key: string\n ): IngressSendClient<VirtualObject<D>> {\n return this.proxy(opts.name, key, true) as IngressSendClient<\n VirtualObject<D>\n >;\n }\n\n serviceSendClient<D>(\n opts: ServiceDefinitionFrom<D>\n ): IngressSendClient<Service<D>> {\n return this.proxy(opts.name, undefined, true) as IngressSendClient<\n Service<D>\n >;\n }\n\n async call<I, O>(opts: {\n service: string;\n handler: string;\n parameter: I;\n key?: string;\n opts?: Opts<I, O>;\n }): Promise<O> {\n return doComponentInvocation<I, O>(this.opts, {\n component: opts.service,\n handler: opts.handler,\n key: opts.key,\n parameter: opts.parameter,\n send: false,\n opts: opts.opts,\n });\n }\n\n async send<I>(opts: {\n service: string;\n handler: string;\n parameter: I;\n key?: string;\n opts?: SendOpts<I>;\n }): Promise<Send> {\n return doComponentInvocation<I, Send>(this.opts, {\n component: opts.service,\n handler: opts.handler,\n key: opts.key,\n parameter: opts.parameter,\n send: true,\n opts: opts.opts,\n });\n }\n\n async resolveAwakeable<T>(\n id: string,\n payload?: T,\n payloadSerde?: Serde<T>\n ): Promise<void> {\n const url = `${this.opts.url}/restate/a/${id}/resolve`;\n const { body, contentType } = serializeBodyWithContentType(\n payload,\n payloadSerde ?? this.opts.serde ?? serde.json,\n this.opts.journalValueCodec\n );\n const headers = {\n ...(this.opts.headers ?? {}),\n };\n if (contentType) {\n headers[\"Content-Type\"] = contentType;\n }\n const httpResponse = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n });\n if (!httpResponse.ok) {\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n }\n }\n\n async rejectAwakeable(id: string, reason: string): Promise<void> {\n const url = `${this.opts.url}/restate/a/${id}/reject`;\n const headers = {\n \"Content-Type\": \"text/plain\",\n ...(this.opts.headers ?? {}),\n };\n const httpResponse = await fetch(url, {\n method: \"POST\",\n headers,\n body: reason,\n });\n if (!httpResponse.ok) {\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n }\n }\n\n async result<T>(\n send: Send<T> | WorkflowSubmission<T>,\n resultSerde?: Serde<T>\n ): Promise<T> {\n if (!send.attachable) {\n throw new Error(\n `Unable to fetch the result for ${send.invocationId}.\n A service's result is stored only with an idempotencyKey is supplied when invocating the service.`\n );\n }\n //\n // headers\n //\n const headers = {\n ...(this.opts.headers ?? {}),\n };\n //\n // make the call\n const url = `${this.opts.url}/restate/invocation/${send.invocationId}/attach`;\n\n const httpResponse = await fetch(url, {\n method: \"GET\",\n headers,\n });\n if (httpResponse.ok) {\n const responseBuf = new Uint8Array(await httpResponse.arrayBuffer());\n const decodedBuf = this.opts.journalValueCodec\n ? await this.opts.journalValueCodec.decode(responseBuf)\n : responseBuf;\n return (resultSerde ?? this.opts.serde ?? serde.json).deserialize(\n decodedBuf\n ) as T;\n }\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n }\n}\n\nfunction computeDelayAsIso(opts: SendOpts): string {\n const delay = opts.delay();\n if (!delay) {\n return \"send\";\n }\n return `send?delay=${delay}ms`;\n}\n\nfunction serializeBodyWithContentType(\n body: unknown,\n serde: Serde<unknown>,\n journalValueCodec?: JournalValueCodec\n): {\n body?: Uint8Array;\n contentType?: string;\n} {\n let buffer = serde.serialize(body);\n if (journalValueCodec) {\n buffer = journalValueCodec.encode(buffer);\n }\n return {\n body: buffer,\n contentType: serde.contentType,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ingress.js","names":["status: number","responseText: string","message: string","parameter: unknown","opts: Opts<unknown, unknown> | SendOpts<unknown> | undefined","url: string","signal: AbortSignal | undefined","body","opts: ConnectionOpts","res: Send","opts","serde"],"sources":["../src/ingress.ts"],"sourcesContent":["/*\n * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH\n *\n * This file is part of the Restate SDK for Node.js/TypeScript,\n * which is released under the MIT license.\n *\n * You can find a copy of the license in file LICENSE in the root\n * directory of this repository or package, or at\n * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE\n */\n\nimport {\n type Service,\n type ServiceDefinitionFrom,\n type VirtualObject,\n type WorkflowDefinitionFrom,\n type Workflow,\n type VirtualObjectDefinitionFrom,\n type Serde,\n serde,\n type JournalValueCodec,\n} from \"@restatedev/restate-sdk-core\";\nimport {\n ConnectionOpts,\n Ingress,\n IngressClient,\n IngressSendClient,\n IngressWorkflowClient,\n Output,\n Send,\n ScopedIngress,\n WorkflowSubmission,\n} from \"./api.js\";\n\nimport { Opts, SendOpts } from \"./api.js\";\n\n/**\n * Connect to the restate Ingress\n *\n * @param opts connection options\n * @returns a connection the the restate ingress\n */\nexport function connect(opts: ConnectionOpts): Ingress {\n return new HttpIngress(opts);\n}\n\nexport class HttpCallError extends Error {\n constructor(\n public readonly status: number,\n public readonly responseText: string,\n public override readonly message: string\n ) {\n super(message);\n }\n}\n\ntype InvocationParameters<I> = {\n component: string;\n handler: string;\n key?: string;\n send?: boolean;\n opts?: Opts<I, unknown> | SendOpts<I>;\n parameter?: I;\n method?: string;\n scope?: string;\n};\n\nfunction optsFromArgs(args: unknown[]): {\n parameter?: unknown;\n opts?: Opts<unknown, unknown> | SendOpts<unknown>;\n} {\n let parameter: unknown;\n let opts: Opts<unknown, unknown> | SendOpts<unknown> | undefined;\n switch (args.length) {\n case 0: {\n break;\n }\n case 1: {\n if (args[0] instanceof Opts) {\n opts = args[0];\n } else if (args[0] instanceof SendOpts) {\n opts = args[0];\n } else {\n parameter = args[0];\n }\n break;\n }\n case 2: {\n parameter = args[0];\n if (args[1] instanceof Opts) {\n opts = args[1];\n } else if (args[1] instanceof SendOpts) {\n opts = args[1];\n } else {\n throw new TypeError(\n \"The second argument must be either Opts or SendOpts\"\n );\n }\n break;\n }\n default: {\n throw new TypeError(\"unexpected number of arguments\");\n }\n }\n return {\n parameter,\n opts,\n };\n}\n\nconst IDEMPOTENCY_KEY_HEADER = \"idempotency-key\";\nconst LIMIT_KEY_HEADER = \"x-restate-limit-key\";\n\nconst doComponentInvocation = async <I, O>(\n opts: ConnectionOpts,\n params: InvocationParameters<I>\n): Promise<O> => {\n let attachable = false;\n //\n // ingress URL\n //\n let url: string;\n if (params.scope) {\n // Scoped path: /restate/scope/{scope}/{call|send}/{service}/{key?}/{handler}\n const pathType = params.send ? \"send\" : \"call\";\n const parts = [\n opts.url,\n \"restate/scope\",\n encodeURIComponent(params.scope),\n pathType,\n params.component,\n ];\n if (params.key) {\n parts.push(encodeURIComponent(params.key));\n }\n parts.push(params.handler);\n url = parts.join(\"/\");\n if (params.send && params.opts instanceof SendOpts) {\n const delay = params.opts.delay();\n if (delay) url += `?delay=${delay}ms`;\n }\n } else {\n const fragments = [opts.url, params.component];\n if (params.key) {\n fragments.push(encodeURIComponent(params.key));\n }\n fragments.push(params.handler);\n if (params.send ?? false) {\n if (params.opts instanceof SendOpts) {\n fragments.push(computeDelayAsIso(params.opts));\n } else {\n fragments.push(\"send\");\n }\n }\n url = fragments.join(\"/\");\n }\n //\n // request body\n //\n const inputSerde = params.opts?.opts.input ?? opts.serde ?? serde.json;\n\n const { body, contentType } = serializeBodyWithContentType(\n params.parameter,\n inputSerde,\n opts.journalValueCodec\n );\n //\n // headers\n //\n const headers = {\n ...(opts.headers ?? {}),\n ...(params.opts?.opts?.headers ?? {}),\n };\n if (contentType) {\n headers[\"Content-Type\"] = contentType;\n }\n //\n // idempotency\n //\n const idempotencyKey = params.opts?.opts.idempotencyKey;\n if (idempotencyKey) {\n headers[IDEMPOTENCY_KEY_HEADER] = idempotencyKey;\n attachable = true;\n }\n //\n // limit key\n //\n const limitKey = params.opts?.opts.limitKey;\n if (limitKey) {\n headers[LIMIT_KEY_HEADER] = limitKey;\n }\n\n // Abort signal, if any\n let signal: AbortSignal | undefined;\n if (\n params.opts?.opts.signal !== undefined &&\n params.opts?.opts.timeout !== undefined\n ) {\n throw new Error(\n \"You can't specify both signal and timeout options at the same time\"\n );\n } else if (params.opts?.opts.signal !== undefined) {\n signal = params.opts?.opts.signal;\n } else if (params.opts?.opts.timeout !== undefined) {\n signal = AbortSignal.timeout(params.opts?.opts.timeout);\n }\n\n //\n // make the call\n //\n const httpResponse = await fetch(url, {\n method: params.method ?? \"POST\",\n headers,\n body,\n signal,\n });\n if (!httpResponse.ok) {\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n }\n const responseBuf = new Uint8Array(await httpResponse.arrayBuffer());\n if (!params.send) {\n const decodedBuf = opts.journalValueCodec\n ? await opts.journalValueCodec.decode(responseBuf)\n : responseBuf;\n const outputSerde = params.opts?.opts.output ?? opts.serde ?? serde.json;\n return outputSerde.deserialize(decodedBuf) as O;\n }\n const json = serde.json.deserialize(responseBuf) as O;\n return { ...json, attachable };\n};\n\nconst doWorkflowHandleCall = async <O>(\n opts: ConnectionOpts,\n wfName: string,\n wfKey: string,\n op: \"output\" | \"attach\",\n callOpts?: Opts<unknown, O> | SendOpts<unknown>\n): Promise<O> => {\n const outputSerde = callOpts?.opts.output ?? opts.serde ?? serde.json;\n //\n // headers\n //\n const headers = {\n ...(opts.headers ?? {}),\n };\n //\n // make the call\n //\n const url = `${opts.url}/restate/workflow/${wfName}/${encodeURIComponent(\n wfKey\n )}/${op}`;\n\n // Abort signal, if any\n let signal: AbortSignal | undefined;\n if (\n callOpts?.opts?.signal !== undefined &&\n callOpts?.opts?.timeout !== undefined\n ) {\n throw new Error(\n \"You can't specify both signal and timeout options at the same time\"\n );\n } else if (callOpts?.opts?.signal !== undefined) {\n signal = callOpts?.opts?.signal;\n } else if (callOpts?.opts?.timeout !== undefined) {\n signal = AbortSignal.timeout(callOpts?.opts?.timeout);\n }\n\n const httpResponse = await fetch(url, {\n method: \"GET\",\n headers,\n signal,\n });\n if (httpResponse.ok) {\n const responseBuf = new Uint8Array(await httpResponse.arrayBuffer());\n const decodedBuf = opts.journalValueCodec\n ? await opts.journalValueCodec.decode(responseBuf)\n : responseBuf;\n return outputSerde.deserialize(decodedBuf) as O;\n }\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n};\n\nclass HttpIngress implements Ingress {\n constructor(private readonly opts: ConnectionOpts) {}\n\n private proxy(component: string, key?: string, send?: boolean) {\n return new Proxy(\n {},\n {\n get: (_target, prop) => {\n const handler = prop as string;\n return (...args: unknown[]) => {\n const { parameter, opts } = optsFromArgs(args);\n return doComponentInvocation<unknown, unknown>(this.opts, {\n component,\n handler,\n key,\n parameter,\n opts,\n send,\n });\n };\n },\n }\n );\n }\n\n serviceClient<D>(opts: ServiceDefinitionFrom<D>): IngressClient<Service<D>> {\n return this.proxy(opts.name) as IngressClient<Service<D>>;\n }\n\n objectClient<D>(\n opts: VirtualObjectDefinitionFrom<D>,\n key: string\n ): IngressClient<VirtualObject<D>> {\n return this.proxy(opts.name, key) as IngressClient<VirtualObject<D>>;\n }\n\n workflowClient<D>(\n opts: WorkflowDefinitionFrom<D>,\n key: string\n ): IngressWorkflowClient<Workflow<D>> {\n const component = opts.name;\n const conn = this.opts;\n\n const workflowSubmit = async (\n ...args: unknown[]\n ): Promise<WorkflowSubmission<unknown>> => {\n const { parameter, opts } = optsFromArgs(args);\n const res: Send = await doComponentInvocation(conn, {\n component,\n handler: \"run\",\n key,\n send: true,\n parameter,\n opts,\n });\n\n return {\n invocationId: res.invocationId,\n status: res.status,\n attachable: true,\n };\n };\n\n const workflowAttach = (opts?: Opts<void, unknown>) =>\n doWorkflowHandleCall(conn, component, key, \"attach\", opts);\n\n const workflowOutput = async (\n opts?: Opts<void, unknown>\n ): Promise<Output<unknown>> => {\n try {\n const result = await doWorkflowHandleCall(\n conn,\n component,\n key,\n \"output\",\n opts\n );\n\n return {\n ready: true,\n result,\n };\n } catch (e) {\n if (!(e instanceof HttpCallError) || e.status !== 470) {\n throw e;\n }\n return {\n ready: false,\n get result() {\n throw new Error(\"Calling result() on a non ready workflow\");\n },\n };\n }\n };\n\n return new Proxy(\n {},\n {\n get: (_target, prop) => {\n const handler = prop as string;\n if (handler === \"workflowSubmit\") {\n return workflowSubmit;\n } else if (handler === \"workflowAttach\") {\n return workflowAttach;\n } else if (handler === \"workflowOutput\") {\n return workflowOutput;\n }\n // shared handlers pass trough via the ingress's normal invocation form\n // i.e. POST /<svc>/<key>/<handler>\n return (...args: unknown[]) => {\n const { parameter, opts } = optsFromArgs(args);\n return doComponentInvocation(conn, {\n component,\n handler,\n key,\n parameter,\n opts,\n });\n };\n },\n }\n ) as IngressWorkflowClient<Workflow<D>>;\n }\n\n objectSendClient<D>(\n opts: VirtualObjectDefinitionFrom<D>,\n key: string\n ): IngressSendClient<VirtualObject<D>> {\n return this.proxy(opts.name, key, true) as IngressSendClient<\n VirtualObject<D>\n >;\n }\n\n serviceSendClient<D>(\n opts: ServiceDefinitionFrom<D>\n ): IngressSendClient<Service<D>> {\n return this.proxy(opts.name, undefined, true) as IngressSendClient<\n Service<D>\n >;\n }\n\n scope(scopeKey: string): ScopedIngress {\n const conn = this.opts;\n const scopedProxy = (component: string, key?: string, send?: boolean) =>\n new Proxy(\n {},\n {\n get: (_target, prop) => {\n const handler = prop as string;\n return (...args: unknown[]) => {\n const { parameter, opts } = optsFromArgs(args);\n return doComponentInvocation<unknown, unknown>(conn, {\n component,\n handler,\n key,\n parameter,\n opts,\n send,\n scope: scopeKey,\n });\n };\n },\n }\n );\n\n return {\n serviceClient: <D>(opts: ServiceDefinitionFrom<D>) =>\n scopedProxy(opts.name) as IngressClient<Service<D>>,\n serviceSendClient: <D>(opts: ServiceDefinitionFrom<D>) =>\n scopedProxy(opts.name, undefined, true) as IngressSendClient<\n Service<D>\n >,\n workflowClient: <D>(\n opts: WorkflowDefinitionFrom<D>,\n key: string\n ): IngressWorkflowClient<Workflow<D>> => {\n const component = opts.name;\n\n const workflowSubmit = async (\n ...args: unknown[]\n ): Promise<WorkflowSubmission<unknown>> => {\n const { parameter, opts } = optsFromArgs(args);\n const res: Send = await doComponentInvocation(conn, {\n component,\n handler: \"run\",\n key,\n send: true,\n parameter,\n opts,\n scope: scopeKey,\n });\n return {\n invocationId: res.invocationId,\n status: res.status,\n attachable: true,\n };\n };\n\n const workflowAttach = (opts?: Opts<void, unknown>) =>\n doWorkflowHandleCall(conn, component, key, \"attach\", opts);\n\n const workflowOutput = async (\n opts?: Opts<void, unknown>\n ): Promise<Output<unknown>> => {\n try {\n const result = await doWorkflowHandleCall(\n conn,\n component,\n key,\n \"output\",\n opts\n );\n return { ready: true, result };\n } catch (e) {\n if (!(e instanceof HttpCallError) || e.status !== 470) {\n throw e;\n }\n return {\n ready: false,\n get result() {\n throw new Error(\"Calling result() on a non ready workflow\");\n },\n };\n }\n };\n\n return new Proxy(\n {},\n {\n get: (_target, prop) => {\n const handler = prop as string;\n if (handler === \"workflowSubmit\") {\n return workflowSubmit;\n } else if (handler === \"workflowAttach\") {\n return workflowAttach;\n } else if (handler === \"workflowOutput\") {\n return workflowOutput;\n }\n return (...args: unknown[]) => {\n const { parameter, opts } = optsFromArgs(args);\n return doComponentInvocation(conn, {\n component,\n handler,\n key,\n parameter,\n opts,\n scope: scopeKey,\n });\n };\n },\n }\n ) as IngressWorkflowClient<Workflow<D>>;\n },\n };\n }\n\n async call<I, O>(opts: {\n service: string;\n handler: string;\n parameter: I;\n key?: string;\n scope?: string;\n opts?: Opts<I, O>;\n }): Promise<O> {\n return doComponentInvocation<I, O>(this.opts, {\n component: opts.service,\n handler: opts.handler,\n key: opts.key,\n scope: opts.scope,\n parameter: opts.parameter,\n send: false,\n opts: opts.opts,\n });\n }\n\n async send<I>(opts: {\n service: string;\n handler: string;\n parameter: I;\n key?: string;\n scope?: string;\n opts?: SendOpts<I>;\n }): Promise<Send> {\n return doComponentInvocation<I, Send>(this.opts, {\n component: opts.service,\n handler: opts.handler,\n key: opts.key,\n scope: opts.scope,\n parameter: opts.parameter,\n send: true,\n opts: opts.opts,\n });\n }\n\n async resolveAwakeable<T>(\n id: string,\n payload?: T,\n payloadSerde?: Serde<T>\n ): Promise<void> {\n const url = `${this.opts.url}/restate/a/${id}/resolve`;\n const { body, contentType } = serializeBodyWithContentType(\n payload,\n payloadSerde ?? this.opts.serde ?? serde.json,\n this.opts.journalValueCodec\n );\n const headers = {\n ...(this.opts.headers ?? {}),\n };\n if (contentType) {\n headers[\"Content-Type\"] = contentType;\n }\n const httpResponse = await fetch(url, {\n method: \"POST\",\n headers,\n body,\n });\n if (!httpResponse.ok) {\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n }\n }\n\n async rejectAwakeable(id: string, reason: string): Promise<void> {\n const url = `${this.opts.url}/restate/a/${id}/reject`;\n const headers = {\n \"Content-Type\": \"text/plain\",\n ...(this.opts.headers ?? {}),\n };\n const httpResponse = await fetch(url, {\n method: \"POST\",\n headers,\n body: reason,\n });\n if (!httpResponse.ok) {\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n }\n }\n\n async result<T>(\n send: Send<T> | WorkflowSubmission<T>,\n resultSerde?: Serde<T>\n ): Promise<T> {\n if (!send.attachable) {\n throw new Error(\n `Unable to fetch the result for ${send.invocationId}.\n A service's result is stored only with an idempotencyKey is supplied when invocating the service.`\n );\n }\n //\n // headers\n //\n const headers = {\n ...(this.opts.headers ?? {}),\n };\n //\n // make the call\n const url = `${this.opts.url}/restate/invocation/${send.invocationId}/attach`;\n\n const httpResponse = await fetch(url, {\n method: \"GET\",\n headers,\n });\n if (httpResponse.ok) {\n const responseBuf = new Uint8Array(await httpResponse.arrayBuffer());\n const decodedBuf = this.opts.journalValueCodec\n ? await this.opts.journalValueCodec.decode(responseBuf)\n : responseBuf;\n return (resultSerde ?? this.opts.serde ?? serde.json).deserialize(\n decodedBuf\n ) as T;\n }\n const body = await httpResponse.text();\n throw new HttpCallError(\n httpResponse.status,\n body,\n `Request failed: ${httpResponse.status}\\n${body}`\n );\n }\n}\n\nfunction computeDelayAsIso(opts: SendOpts): string {\n const delay = opts.delay();\n if (!delay) {\n return \"send\";\n }\n return `send?delay=${delay}ms`;\n}\n\nfunction serializeBodyWithContentType(\n body: unknown,\n serde: Serde<unknown>,\n journalValueCodec?: JournalValueCodec\n): {\n body?: Uint8Array;\n contentType?: string;\n} {\n let buffer = serde.serialize(body);\n if (journalValueCodec) {\n buffer = journalValueCodec.encode(buffer);\n }\n return {\n body: buffer,\n contentType: serde.contentType,\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@restatedev/restate-sdk-clients",
3
- "version": "1.15.0-rc.7",
3
+ "version": "1.15.0",
4
4
  "description": "Typescript SDK for Restate",
5
5
  "author": "Restate Developers",
6
6
  "email": "code@restate.dev",
@@ -32,7 +32,7 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@restatedev/restate-sdk-core": "1.15.0-rc.7"
35
+ "@restatedev/restate-sdk-core": "1.15.0"
36
36
  },
37
37
  "devDependencies": {},
38
38
  "scripts": {