js-bao-wss-client 2.0.6 → 2.0.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.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/dist/JsBaoClient.d.ts +71 -47
  3. package/dist/JsBaoClient.d.ts.map +1 -1
  4. package/dist/JsBaoClient.js +93 -10
  5. package/dist/JsBaoClient.js.map +1 -1
  6. package/dist/api/cacheFacade.d.ts +6 -6
  7. package/dist/api/cacheFacade.d.ts.map +1 -1
  8. package/dist/api/cacheFacade.js.map +1 -1
  9. package/dist/api/collectionTypeConfigsApi.d.ts +23 -0
  10. package/dist/api/collectionTypeConfigsApi.d.ts.map +1 -1
  11. package/dist/api/collectionTypeConfigsApi.js.map +1 -1
  12. package/dist/api/collectionsApi.d.ts +15 -0
  13. package/dist/api/collectionsApi.d.ts.map +1 -1
  14. package/dist/api/collectionsApi.js.map +1 -1
  15. package/dist/api/cronTriggersApi.d.ts +4 -4
  16. package/dist/api/cronTriggersApi.d.ts.map +1 -1
  17. package/dist/api/databaseTypeConfigsApi.d.ts +104 -1
  18. package/dist/api/databaseTypeConfigsApi.d.ts.map +1 -1
  19. package/dist/api/databaseTypeConfigsApi.js.map +1 -1
  20. package/dist/api/databasesApi.d.ts +63 -22
  21. package/dist/api/databasesApi.d.ts.map +1 -1
  22. package/dist/api/databasesApi.js +22 -2
  23. package/dist/api/databasesApi.js.map +1 -1
  24. package/dist/api/documentsApi.d.ts +16 -4
  25. package/dist/api/documentsApi.d.ts.map +1 -1
  26. package/dist/api/documentsApi.js +16 -0
  27. package/dist/api/documentsApi.js.map +1 -1
  28. package/dist/api/geminiApi.d.ts +9 -9
  29. package/dist/api/geminiApi.d.ts.map +1 -1
  30. package/dist/api/geminiApi.js.map +1 -1
  31. package/dist/api/invitationsApi.d.ts +15 -3
  32. package/dist/api/invitationsApi.d.ts.map +1 -1
  33. package/dist/api/invitationsApi.js +15 -3
  34. package/dist/api/invitationsApi.js.map +1 -1
  35. package/dist/api/llmApi.d.ts +8 -8
  36. package/dist/api/llmApi.d.ts.map +1 -1
  37. package/dist/api/llmApi.js.map +1 -1
  38. package/dist/api/notificationsApi.d.ts +2 -2
  39. package/dist/api/ruleSetsApi.d.ts +57 -11
  40. package/dist/api/ruleSetsApi.d.ts.map +1 -1
  41. package/dist/api/ruleSetsApi.js.map +1 -1
  42. package/dist/browser.umd.js +278 -36
  43. package/dist/browser.umd.js.map +1 -1
  44. package/dist/internal/blobManager.d.ts +5 -5
  45. package/dist/internal/blobManager.d.ts.map +1 -1
  46. package/dist/internal/blobManager.js.map +1 -1
  47. package/dist/internal/documentManager.d.ts +1 -0
  48. package/dist/internal/documentManager.d.ts.map +1 -1
  49. package/dist/internal/documentManager.js.map +1 -1
  50. package/dist/internal/httpClient.d.ts +58 -1
  51. package/dist/internal/httpClient.d.ts.map +1 -1
  52. package/dist/internal/httpClient.js +132 -21
  53. package/dist/internal/httpClient.js.map +1 -1
  54. package/package.json +1 -1
@@ -41,6 +41,24 @@ export { ANALYTICS_UNAUTHENTICATED_USER } from "./internal/analyticsQueue";
41
41
  const DEFAULT_RETURN_ACTIVE_MIN_MS = 5 * 60 * 1000;
42
42
  const DEFAULT_SYNC_ERROR_MIN_MS = 30 * 1000;
43
43
  const logger = createLogger({ scope: "JsBaoClient" });
44
+ // Workflow apply-lifecycle durability (#1694). The server confirm is idempotent
45
+ // (read-then-conditional-write; returns `confirmed: true` if the run already
46
+ // completed), so a lost or hung confirm POST is safe to retry — retrying only
47
+ // re-sends the confirm, never the user's onApply handler. These bounds keep the
48
+ // retry inside the server's 30s apply lease so a stranded run recovers within
49
+ // the same client session instead of waiting for a full restart.
50
+ //
51
+ // A per-request timeout (via AbortController in the HTTP layer) turns a hung
52
+ // apply POST into a retryable network error. Scope note: this timeout is applied
53
+ // only to the apply-lifecycle calls (claim/confirm/release), not to every client
54
+ // request — a blanket request timeout has a much larger blast radius.
55
+ const APPLY_REQUEST_TIMEOUT_MS = 8000;
56
+ const APPLY_CONFIRM_MAX_ATTEMPTS = 6;
57
+ const APPLY_CONFIRM_BASE_DELAY_MS = 250;
58
+ const APPLY_CONFIRM_MAX_DELAY_MS = 4000;
59
+ // Total retry budget, kept under the 30s server apply lease so the claim is
60
+ // still valid when a retry finally lands.
61
+ const APPLY_CONFIRM_RETRY_BUDGET_MS = 25000;
44
62
  function debugLog(tag, payload) {
45
63
  try {
46
64
  if (!logger.shouldLog("debug"))
@@ -2624,7 +2642,9 @@ export class JsBaoClient extends Observable {
2624
2642
  if (options.contextDocId) {
2625
2643
  payload.contextDocId = options.contextDocId;
2626
2644
  }
2627
- const response = await this.makeRequest("POST", path, payload);
2645
+ const response = await this.makeRequest("POST", path, payload, {
2646
+ timeoutMs: APPLY_REQUEST_TIMEOUT_MS,
2647
+ });
2628
2648
  return response;
2629
2649
  }
2630
2650
  async releaseWorkflowApply(options) {
@@ -2635,7 +2655,9 @@ export class JsBaoClient extends Observable {
2635
2655
  if (options.contextDocId) {
2636
2656
  payload.contextDocId = options.contextDocId;
2637
2657
  }
2638
- const response = await this.makeRequest("POST", path, payload);
2658
+ const response = await this.makeRequest("POST", path, payload, {
2659
+ timeoutMs: APPLY_REQUEST_TIMEOUT_MS,
2660
+ });
2639
2661
  return response;
2640
2662
  }
2641
2663
  async confirmWorkflowApply(options) {
@@ -2652,9 +2674,63 @@ export class JsBaoClient extends Observable {
2652
2674
  if (options.contextDocId) {
2653
2675
  payload.contextDocId = options.contextDocId;
2654
2676
  }
2655
- const response = await this.makeRequest("POST", path, payload);
2677
+ const response = await this.makeRequest("POST", path, payload, {
2678
+ timeoutMs: APPLY_REQUEST_TIMEOUT_MS,
2679
+ });
2656
2680
  return response;
2657
2681
  }
2682
+ /**
2683
+ * Whether a thrown confirm-apply error is worth retrying. Network failures
2684
+ * (unreachable server, refused connection, DNS failure, or an aborted
2685
+ * timeout — all surfaced as `JsBaoNetworkError`) and HTTP 5xx are transient,
2686
+ * so retrying the idempotent confirm may still succeed. Any other HTTP status
2687
+ * (4xx) is a definitive rejection and is not retried.
2688
+ */
2689
+ isRetryableConfirmError(err) {
2690
+ if (err instanceof JsBaoNetworkError) {
2691
+ return true;
2692
+ }
2693
+ if (err instanceof JsBaoApiError) {
2694
+ return err.status >= 500 && err.status < 600;
2695
+ }
2696
+ return false;
2697
+ }
2698
+ /**
2699
+ * Retry the confirm POST on transient failures, bounded by both an attempt
2700
+ * count and a time budget that stays within the server's apply lease. Only
2701
+ * the confirm POST is retried here — the caller runs the user's onApply
2702
+ * handler exactly once, before invoking this, so retries never re-run it.
2703
+ * A `confirmed: false` result (a genuine claim loss) is returned normally,
2704
+ * not retried; the caller releases the claim in that case.
2705
+ */
2706
+ async confirmWorkflowApplyWithRetry(options) {
2707
+ const deadline = Date.now() + APPLY_CONFIRM_RETRY_BUDGET_MS;
2708
+ let attempt = 0;
2709
+ let delayMs = APPLY_CONFIRM_BASE_DELAY_MS;
2710
+ for (;;) {
2711
+ attempt++;
2712
+ try {
2713
+ return await this.confirmWorkflowApply(options);
2714
+ }
2715
+ catch (err) {
2716
+ const nextDelay = Math.min(delayMs, APPLY_CONFIRM_MAX_DELAY_MS);
2717
+ const outOfBudget = Date.now() + nextDelay >= deadline;
2718
+ if (!this.isRetryableConfirmError(err) ||
2719
+ attempt >= APPLY_CONFIRM_MAX_ATTEMPTS ||
2720
+ outOfBudget) {
2721
+ throw err;
2722
+ }
2723
+ logger.warn("[workflowApply] confirm failed, retrying", {
2724
+ workflowKey: options.workflowKey,
2725
+ runKey: options.runKey,
2726
+ attempt,
2727
+ error: err instanceof Error ? err.message : String(err),
2728
+ });
2729
+ await new Promise((resolve) => setTimeout(resolve, nextDelay));
2730
+ delayMs = Math.min(delayMs * 2, APPLY_CONFIRM_MAX_DELAY_MS);
2731
+ }
2732
+ }
2733
+ }
2658
2734
  async getWorkflowPendingApplies(options) {
2659
2735
  if (!options?.contextDocId) {
2660
2736
  throw new JsBaoError("INVALID_ARGUMENT", "contextDocId is required for workflows.getPendingApplies");
@@ -2702,11 +2778,15 @@ export class JsBaoClient extends Observable {
2702
2778
  startedByUserId: event.startedByUserId,
2703
2779
  meta: statusResult.run?.meta ?? undefined,
2704
2780
  });
2705
- // Confirm the apply. Surface a server-side rejection (`confirmed: false`)
2706
- // as an error so we don't silently leave the workflow stuck in
2707
- // `apply_claimed` (issue #614). The catch block below releases the
2708
- // claim and emits a diagnostic.
2709
- const confirmResult = await this.confirmWorkflowApply({
2781
+ // Confirm the apply, retrying the POST on transient failures (#1694).
2782
+ // The handler above has already run exactly once; the retry re-sends only
2783
+ // the idempotent confirm, never the handler. A lost or hung confirm would
2784
+ // otherwise strand the run in `apply_claimed` for the whole client session
2785
+ // with no way to recover short of a restart. Surface a server-side
2786
+ // rejection (`confirmed: false`) as an error so we don't silently leave
2787
+ // the workflow stuck in `apply_claimed` (issue #614). The catch block
2788
+ // below releases the claim and emits a diagnostic.
2789
+ const confirmResult = await this.confirmWorkflowApplyWithRetry({
2710
2790
  workflowKey: event.workflowKey,
2711
2791
  runKey: event.runKey,
2712
2792
  contextDocId: event.contextDocId,
@@ -2716,7 +2796,10 @@ export class JsBaoClient extends Observable {
2716
2796
  }
2717
2797
  }
2718
2798
  catch (err) {
2719
- logger.warn("[workflowApply] apply handler failed", {
2799
+ // Elevated to `error` (#1694): apply-flow failures strand a run in
2800
+ // `apply_claimed`, and tests (and apps) commonly run at logLevel `error`,
2801
+ // so a `warn`/`debug` diagnostic here is invisible exactly when it matters.
2802
+ logger.error("[workflowApply] apply handler failed", {
2720
2803
  workflowKey: event.workflowKey,
2721
2804
  runKey: event.runKey,
2722
2805
  error: err instanceof Error ? err.message : String(err),
@@ -2730,7 +2813,7 @@ export class JsBaoClient extends Observable {
2730
2813
  });
2731
2814
  }
2732
2815
  catch (releaseErr) {
2733
- logger.debug("[workflowApply] failed to release claim", {
2816
+ logger.error("[workflowApply] failed to release claim", {
2734
2817
  workflowKey: event.workflowKey,
2735
2818
  runKey: event.runKey,
2736
2819
  error: releaseErr instanceof Error ? releaseErr.message : String(releaseErr),