js-bao-wss-client 2.2.0-alpha.6 → 2.2.0-alpha.7

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.
@@ -93,7 +93,7 @@ export type { DocumentDebugSnapshot, DocumentPermission, LocalDocumentEntry, Loc
93
93
  export type { LogLevel } from "./internal/logger";
94
94
  export type { RequestOptions } from "./internal/httpClient";
95
95
  export type { LocksAPI } from "./api/locksApi";
96
- export type { FunctionsAPI, FunctionInvokeOptions, FunctionInvokeResult, FunctionInvokeStatus, FunctionInvokeLimits, FunctionStartOptions, FunctionStartResult, FunctionRunRef, } from "./api/functionsApi";
96
+ export type { FunctionsAPI, FunctionInvokeOptions, FunctionInvokeResult, FunctionInvokeStatus, FunctionInvokeLimits, FunctionStartOptions, FunctionStartResult, FunctionRunRef, FunctionWaitForResult, } from "./api/functionsApi";
97
97
  export type { LockHandle, LockContention, AcquireResponse, AcquireOptions, BlockingAcquireOptions, ReleaseResult, RenewResult, LockStatus, LockListEntry, LockListResult, } from "./api/locksApi";
98
98
  export type { ResourceMetadataAPI } from "./api/resourceMetadataApi";
99
99
  export type { ResourceMetadataReadResult, ResourceMetadataWriteResult, ResourceMetadataBatchRequestItem, ResourceMetadataBatchParams, ResourceMetadataBatchCategoryResult, ResourceMetadataBatchResourceResult, ResourceMetadataBatchResult, ResourceMetadataListEntry, ResourceMetadataListResult, ResourceMetadataDeleteResult, ResourceMetadataResolveParams, ResourceMetadataResolveResult, } from "./api/resourceMetadataApi";
@@ -1,12 +1,12 @@
1
- import type { JsBaoClient, ClaimApplyResult, ConfirmApplyResult, ReleaseApplyResult, WaitForWorkflowOptions, WaitForWorkflowResult, WorkflowStatusResult } from "../JsBaoClient";
1
+ import type { JsBaoClient, WaitForWorkflowOptions, WaitForWorkflowResult, WorkflowStatusResult } from "../JsBaoClient";
2
2
  /**
3
3
  * Server functions — client surface.
4
4
  *
5
5
  * A function is TypeScript an app's team authored, pushed with `primitive
6
6
  * config push`, and invokes over HTTP. This is the whole client contract for
7
- * the synchronous path; durable functions add to it without changing it.
7
+ * the request path; task functions add to it without changing it.
8
8
  */
9
- /** How a synchronous invocation settled. */
9
+ /** How a request invocation settled. */
10
10
  export type FunctionInvokeStatus = "completed" | "failed" | "timeout";
11
11
  /**
12
12
  * The resolved platform ceilings an invocation ran under.
@@ -24,7 +24,7 @@ export interface FunctionInvokeLimits {
24
24
  /**
25
25
  * The invoke envelope.
26
26
  *
27
- * Deliberately without a `runId`: the synchronous path writes no run row, so
27
+ * Deliberately without a `runId`: the request path writes no run row, so
28
28
  * there is nothing to look up afterwards. A function that throws or times out
29
29
  * is a settled invocation with a terminal `status`, NOT a transport error —
30
30
  * only the platform refusing the call before the code ran (access, disabled,
@@ -64,7 +64,7 @@ export interface FunctionInvokeOptions<TInput = unknown> {
64
64
  timeoutMs?: number;
65
65
  }
66
66
  /**
67
- * The workflow START envelope, which a durable function answers with.
67
+ * The workflow START envelope, which a task function answers with.
68
68
  *
69
69
  * Identical to what `workflows.start` returns, deliberately: intent criterion 2
70
70
  * is that a caller "polls its run id exactly as for a DSL workflow today", and
@@ -80,7 +80,7 @@ export interface FunctionStartResult {
80
80
  output?: unknown;
81
81
  error?: string;
82
82
  }
83
- /** What to send with a durable start. */
83
+ /** What to send with a task start. */
84
84
  export interface FunctionStartOptions<TInput = unknown> {
85
85
  /** The value the handler receives as its `input` (travels as `rootInput`). */
86
86
  input?: TInput;
@@ -94,6 +94,14 @@ export interface FunctionStartOptions<TInput = unknown> {
94
94
  /** Caller metadata, at most 1 KB encoded. */
95
95
  meta?: Record<string, unknown>;
96
96
  }
97
+ /**
98
+ * What `functions.waitFor` resolves with: the terminal workflow-wait envelope
99
+ * with `output` typed by the caller's generic rather than inherited as `any`.
100
+ * `TOutput` defaults to `any`, so a bare caller is unchanged.
101
+ */
102
+ export type FunctionWaitForResult<TOutput = any> = Omit<WaitForWorkflowResult, "output"> & {
103
+ output?: TOutput;
104
+ };
97
105
  /**
98
106
  * Addressing one function run for the control routes.
99
107
  *
@@ -125,7 +133,7 @@ export declare class FunctionsAPI {
125
133
  */
126
134
  invoke<TOutput = unknown, TInput = unknown>(functionKey: string, options?: FunctionInvokeOptions<TInput>): Promise<FunctionInvokeResult<TOutput>>;
127
135
  /**
128
- * Start a DURABLE server function and get its run id back.
136
+ * Start a TASK server function and get its run id back.
129
137
  *
130
138
  * The run is polled on exactly the routes a DSL workflow run is, which is
131
139
  * why the methods below are aliases rather than a parallel protocol.
@@ -155,33 +163,13 @@ export declare class FunctionsAPI {
155
163
  * The interval starts short and backs off, so a function that finishes in a
156
164
  * second is not waited out and one that sleeps for an hour is not polled
157
165
  * thousands of times.
166
+ *
167
+ * `output` is typed by `TOutput`: the inherited `WaitForWorkflowResult.output`
168
+ * is `any`, and an intersection with `any` is `any`, so the inherited member
169
+ * is replaced rather than intersected. With the default `any` a caller that
170
+ * never named `TOutput` reads exactly what it did.
158
171
  */
159
- waitFor<TOutput = unknown>(runId: string, options?: WaitForWorkflowOptions): Promise<WaitForWorkflowResult & {
160
- output?: TOutput;
161
- }>;
172
+ waitFor<TOutput = any>(runId: string, options?: WaitForWorkflowOptions): Promise<FunctionWaitForResult<TOutput>>;
162
173
  /** Terminate a running function run. */
163
174
  terminate<TOutput = unknown>(ref: FunctionRunRef): Promise<WorkflowStatusResult<TOutput>>;
164
- /**
165
- * Claim a function run's result for a client-side apply.
166
- *
167
- * Kept for shape parity with workflow runs: a function run never enters the
168
- * apply flow (nothing on this path produces a client-apply payload), so this
169
- * answers the existing refusal rather than being absent. A caller writing one
170
- * code path over both kinds of run gets the same envelope either way.
171
- */
172
- claimApply(ref: FunctionRunRef): Promise<ClaimApplyResult>;
173
- /**
174
- * Release a claimed apply so another client can retry it.
175
- *
176
- * Kept for shape parity with workflow runs; a function run has no
177
- * client-apply step to release, so this answers the existing refusal.
178
- */
179
- releaseApply(ref: FunctionRunRef): Promise<ReleaseApplyResult>;
180
- /**
181
- * Confirm that a claimed apply has been written to the document.
182
- *
183
- * Kept for shape parity with workflow runs; a function run has no
184
- * client-apply step to confirm, so this answers the existing refusal.
185
- */
186
- confirmApply(ref: FunctionRunRef): Promise<ConfirmApplyResult>;
187
175
  }
@@ -26,19 +26,20 @@ export class FunctionsAPI {
26
26
  ? {}
27
27
  : { timeoutMs: options.timeoutMs }),
28
28
  });
29
- // The route is one route and the MODE decides what it answers. A durable
29
+ // The route is one route and the MODE decides what it answers. A task
30
30
  // function answers the start envelope, which has no `output` and no
31
31
  // terminal `status` — everything this method's return type promises. Say
32
32
  // so, rather than handing back an object whose `output` is undefined for a
33
- // run that has not finished (#3186).
33
+ // run that has not finished (#3186). In the mode words (#3281): the config
34
+ // key is `mode = "request" | "task"`, and the message speaks it.
34
35
  if (isStartEnvelope(response)) {
35
- throw new JsBaoError("FUNCTION_MODE_MISMATCH", `Function '${functionKey}' is durable: it starts a RUN rather than returning a result. ` +
36
+ throw new JsBaoError("FUNCTION_MODE_MISMATCH", `Function '${functionKey}' is a task function: it starts a RUN rather than returning a result. ` +
36
37
  `Call functions.start(key, options) and poll with functions.getStatus / functions.waitFor.`, { functionKey, runId: response.runId });
37
38
  }
38
39
  return response;
39
40
  }
40
41
  /**
41
- * Start a DURABLE server function and get its run id back.
42
+ * Start a TASK server function and get its run id back.
42
43
  *
43
44
  * The run is polled on exactly the routes a DSL workflow run is, which is
44
45
  * why the methods below are aliases rather than a parallel protocol.
@@ -54,11 +55,11 @@ export class FunctionsAPI {
54
55
  ...(options.contextDocId ? { contextDocId: options.contextDocId } : {}),
55
56
  ...(options.meta ? { meta: options.meta } : {}),
56
57
  });
57
- // The mirror of the check in `invoke`: a synchronous function ran and
58
+ // The mirror of the check in `invoke`: a request function ran and
58
59
  // answered with its RESULT, so there is no run id to poll and every method
59
60
  // below would have nothing to address.
60
61
  if (!isStartEnvelope(response)) {
61
- throw new JsBaoError("FUNCTION_MODE_MISMATCH", `Function '${functionKey}' is synchronous: it returns a result rather than starting a run. ` +
62
+ throw new JsBaoError("FUNCTION_MODE_MISMATCH", `Function '${functionKey}' is a request function: it returns a result rather than starting a run. ` +
62
63
  `Call functions.invoke(key, options) instead.`, { functionKey, status: response?.status });
63
64
  }
64
65
  return response;
@@ -95,6 +96,11 @@ export class FunctionsAPI {
95
96
  * The interval starts short and backs off, so a function that finishes in a
96
97
  * second is not waited out and one that sleeps for an hour is not polled
97
98
  * thousands of times.
99
+ *
100
+ * `output` is typed by `TOutput`: the inherited `WaitForWorkflowResult.output`
101
+ * is `any`, and an intersection with `any` is `any`, so the inherited member
102
+ * is replaced rather than intersected. With the default `any` a caller that
103
+ * never named `TOutput` reads exactly what it did.
98
104
  */
99
105
  async waitFor(runId, options) {
100
106
  if (!runId || typeof runId !== "string") {
@@ -134,35 +140,6 @@ export class FunctionsAPI {
134
140
  async terminate(ref) {
135
141
  return this.client.workflows.terminate(asWorkflowRef(ref));
136
142
  }
137
- /**
138
- * Claim a function run's result for a client-side apply.
139
- *
140
- * Kept for shape parity with workflow runs: a function run never enters the
141
- * apply flow (nothing on this path produces a client-apply payload), so this
142
- * answers the existing refusal rather than being absent. A caller writing one
143
- * code path over both kinds of run gets the same envelope either way.
144
- */
145
- async claimApply(ref) {
146
- return this.client.workflows.claimApply(asWorkflowRef(ref));
147
- }
148
- /**
149
- * Release a claimed apply so another client can retry it.
150
- *
151
- * Kept for shape parity with workflow runs; a function run has no
152
- * client-apply step to release, so this answers the existing refusal.
153
- */
154
- async releaseApply(ref) {
155
- return this.client.workflows.releaseApply(asWorkflowRef(ref));
156
- }
157
- /**
158
- * Confirm that a claimed apply has been written to the document.
159
- *
160
- * Kept for shape parity with workflow runs; a function run has no
161
- * client-apply step to confirm, so this answers the existing refusal.
162
- */
163
- async confirmApply(ref) {
164
- return this.client.workflows.confirmApply(asWorkflowRef(ref));
165
- }
166
143
  }
167
144
  /** 15 minutes, matching `workflows.waitFor`'s default. */
168
145
  const FUNCTION_WAIT_DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;
@@ -197,9 +174,9 @@ function asWorkflowRef(ref) {
197
174
  /**
198
175
  * Is this the workflow START envelope rather than a settled invocation?
199
176
  *
200
- * `runId` is the discriminator, and it is a good one: the synchronous path
177
+ * `runId` is the discriminator, and it is a good one: the request path
201
178
  * writes no run row precisely so that there is nothing to poll, so a `runId` on
202
- * this route means a durable start and nothing else.
179
+ * this route means a task start and nothing else.
203
180
  */
204
181
  function isStartEnvelope(value) {
205
182
  return (value !== null &&
@@ -4407,7 +4407,6 @@
4407
4407
  browser_version: event.browser_version ?? device.browserVersion,
4408
4408
  app_version: event.app_version,
4409
4409
  context_json: truncatedContext,
4410
- user_created_at_epoch_s: event.user_created_at_epoch_s,
4411
4410
  };
4412
4411
  }
4413
4412
  function chunkBySize(events, connectionId) {
@@ -14981,19 +14980,20 @@
14981
14980
  ? {}
14982
14981
  : { timeoutMs: options.timeoutMs }),
14983
14982
  });
14984
- // The route is one route and the MODE decides what it answers. A durable
14983
+ // The route is one route and the MODE decides what it answers. A task
14985
14984
  // function answers the start envelope, which has no `output` and no
14986
14985
  // terminal `status` — everything this method's return type promises. Say
14987
14986
  // so, rather than handing back an object whose `output` is undefined for a
14988
- // run that has not finished (#3186).
14987
+ // run that has not finished (#3186). In the mode words (#3281): the config
14988
+ // key is `mode = "request" | "task"`, and the message speaks it.
14989
14989
  if (isStartEnvelope(response)) {
14990
- throw new JsBaoError("FUNCTION_MODE_MISMATCH", `Function '${functionKey}' is durable: it starts a RUN rather than returning a result. ` +
14990
+ throw new JsBaoError("FUNCTION_MODE_MISMATCH", `Function '${functionKey}' is a task function: it starts a RUN rather than returning a result. ` +
14991
14991
  `Call functions.start(key, options) and poll with functions.getStatus / functions.waitFor.`, { functionKey, runId: response.runId });
14992
14992
  }
14993
14993
  return response;
14994
14994
  }
14995
14995
  /**
14996
- * Start a DURABLE server function and get its run id back.
14996
+ * Start a TASK server function and get its run id back.
14997
14997
  *
14998
14998
  * The run is polled on exactly the routes a DSL workflow run is, which is
14999
14999
  * why the methods below are aliases rather than a parallel protocol.
@@ -15009,11 +15009,11 @@
15009
15009
  ...(options.contextDocId ? { contextDocId: options.contextDocId } : {}),
15010
15010
  ...(options.meta ? { meta: options.meta } : {}),
15011
15011
  });
15012
- // The mirror of the check in `invoke`: a synchronous function ran and
15012
+ // The mirror of the check in `invoke`: a request function ran and
15013
15013
  // answered with its RESULT, so there is no run id to poll and every method
15014
15014
  // below would have nothing to address.
15015
15015
  if (!isStartEnvelope(response)) {
15016
- throw new JsBaoError("FUNCTION_MODE_MISMATCH", `Function '${functionKey}' is synchronous: it returns a result rather than starting a run. ` +
15016
+ throw new JsBaoError("FUNCTION_MODE_MISMATCH", `Function '${functionKey}' is a request function: it returns a result rather than starting a run. ` +
15017
15017
  `Call functions.invoke(key, options) instead.`, { functionKey, status: response?.status });
15018
15018
  }
15019
15019
  return response;
@@ -15050,6 +15050,11 @@
15050
15050
  * The interval starts short and backs off, so a function that finishes in a
15051
15051
  * second is not waited out and one that sleeps for an hour is not polled
15052
15052
  * thousands of times.
15053
+ *
15054
+ * `output` is typed by `TOutput`: the inherited `WaitForWorkflowResult.output`
15055
+ * is `any`, and an intersection with `any` is `any`, so the inherited member
15056
+ * is replaced rather than intersected. With the default `any` a caller that
15057
+ * never named `TOutput` reads exactly what it did.
15053
15058
  */
15054
15059
  async waitFor(runId, options) {
15055
15060
  if (!runId || typeof runId !== "string") {
@@ -15089,35 +15094,6 @@
15089
15094
  async terminate(ref) {
15090
15095
  return this.client.workflows.terminate(asWorkflowRef(ref));
15091
15096
  }
15092
- /**
15093
- * Claim a function run's result for a client-side apply.
15094
- *
15095
- * Kept for shape parity with workflow runs: a function run never enters the
15096
- * apply flow (nothing on this path produces a client-apply payload), so this
15097
- * answers the existing refusal rather than being absent. A caller writing one
15098
- * code path over both kinds of run gets the same envelope either way.
15099
- */
15100
- async claimApply(ref) {
15101
- return this.client.workflows.claimApply(asWorkflowRef(ref));
15102
- }
15103
- /**
15104
- * Release a claimed apply so another client can retry it.
15105
- *
15106
- * Kept for shape parity with workflow runs; a function run has no
15107
- * client-apply step to release, so this answers the existing refusal.
15108
- */
15109
- async releaseApply(ref) {
15110
- return this.client.workflows.releaseApply(asWorkflowRef(ref));
15111
- }
15112
- /**
15113
- * Confirm that a claimed apply has been written to the document.
15114
- *
15115
- * Kept for shape parity with workflow runs; a function run has no
15116
- * client-apply step to confirm, so this answers the existing refusal.
15117
- */
15118
- async confirmApply(ref) {
15119
- return this.client.workflows.confirmApply(asWorkflowRef(ref));
15120
- }
15121
15097
  }
15122
15098
  /** 15 minutes, matching `workflows.waitFor`'s default. */
15123
15099
  const FUNCTION_WAIT_DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;
@@ -15152,9 +15128,9 @@
15152
15128
  /**
15153
15129
  * Is this the workflow START envelope rather than a settled invocation?
15154
15130
  *
15155
- * `runId` is the discriminator, and it is a good one: the synchronous path
15131
+ * `runId` is the discriminator, and it is a good one: the request path
15156
15132
  * writes no run row precisely so that there is nothing to poll, so a `runId` on
15157
- * this route means a durable start and nothing else.
15133
+ * this route means a task start and nothing else.
15158
15134
  */
15159
15135
  function isStartEnvelope(value) {
15160
15136
  return (value !== null &&
@@ -27,6 +27,10 @@ export interface AnalyticsEventInput {
27
27
  browser_version?: string;
28
28
  app_version?: string;
29
29
  context_json?: Record<string, unknown> | string | null;
30
+ /**
31
+ * @deprecated Ignored. The server records when the user joined the app; any
32
+ * value passed here is dropped before the event is sent.
33
+ */
30
34
  user_created_at_epoch_s?: number;
31
35
  }
32
36
  export interface AnalyticsPreparedEvent {
@@ -44,7 +48,6 @@ export interface AnalyticsPreparedEvent {
44
48
  browser_version?: string;
45
49
  app_version?: string;
46
50
  context_json?: string;
47
- user_created_at_epoch_s?: number;
48
51
  }
49
52
  export interface AnalyticsBatchMessage {
50
53
  type: typeof ANALYTICS_MESSAGE_TYPE;
@@ -206,7 +206,6 @@ export function createAnalyticsQueue(options) {
206
206
  browser_version: event.browser_version ?? device.browserVersion,
207
207
  app_version: event.app_version,
208
208
  context_json: truncatedContext,
209
- user_created_at_epoch_s: event.user_created_at_epoch_s,
210
209
  };
211
210
  }
212
211
  function chunkBySize(events, connectionId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-bao-wss-client",
3
- "version": "2.2.0-alpha.6",
3
+ "version": "2.2.0-alpha.7",
4
4
  "description": "Client library for js-bao-wss Yjs WebSocket service",
5
5
  "author": "Primitive LLC",
6
6
  "license": "UNLICENSED",
@@ -36,7 +36,7 @@
36
36
  "peerDependencies": {
37
37
  "lib0": "^0.2.0",
38
38
  "yjs": "^13.6.0",
39
- "js-bao": "0.7.0-alpha.1",
39
+ "js-bao": "0.7.0-alpha.2",
40
40
  "better-sqlite3": "^11.0.0",
41
41
  "y-sqlite3": "^0.1.0",
42
42
  "react": ">=17.0.0",