@mdbase-dev/connect 0.1.0-beta.125 → 0.1.0-beta.147

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 (49) hide show
  1. package/dist/application-session.d.ts +1 -1
  2. package/dist/application-session.js +1 -1
  3. package/dist/async.d.ts +6 -0
  4. package/dist/async.js +39 -0
  5. package/dist/authorization-refresh.d.ts +2 -0
  6. package/dist/authorization-refresh.js +13 -1
  7. package/dist/browser/integrity.json +1 -1
  8. package/dist/browser/mdbase-connect.min.js +4 -4
  9. package/dist/browser/mdbase-connect.min.js.sha384 +1 -1
  10. package/dist/capabilities.d.ts +1 -1
  11. package/dist/collection-client.d.ts +2 -0
  12. package/dist/collection-client.js +8 -4
  13. package/dist/connect-options.d.ts +1 -1
  14. package/dist/connect.d.ts +1 -1
  15. package/dist/connect.js +1 -1
  16. package/dist/connection.d.ts +2 -1
  17. package/dist/connection.js +3 -1
  18. package/dist/control-timers.d.ts +43 -0
  19. package/dist/control-timers.js +290 -0
  20. package/dist/errors.d.ts +2 -28
  21. package/dist/errors.js +2 -52
  22. package/dist/file-transfer-internals.d.ts +2 -1
  23. package/dist/file-transfer-internals.js +10 -3
  24. package/dist/files.d.ts +4 -0
  25. package/dist/files.js +17 -18
  26. package/dist/index.d.ts +2 -1
  27. package/dist/index.js +1 -0
  28. package/dist/internal-types.d.ts +2 -2
  29. package/dist/internal-types.js +1 -1
  30. package/dist/mdbase-connect.d.ts +1 -1
  31. package/dist/observe.d.ts +81 -0
  32. package/dist/observe.js +390 -0
  33. package/dist/operation-types.d.ts +3 -1
  34. package/dist/outcomes.d.ts +13 -13
  35. package/dist/outcomes.js +17 -0
  36. package/dist/query-pagination-internals.d.ts +1 -1
  37. package/dist/query-pagination-internals.js +4 -2
  38. package/dist/query-pagination.js +1 -1
  39. package/dist/query-wire.d.ts +16 -10
  40. package/dist/query-wire.js +44 -13
  41. package/dist/read-many.js +4 -2
  42. package/dist/runtime-utils.d.ts +1 -1
  43. package/dist/saved-view-pagination.js +1 -1
  44. package/dist/session.d.ts +1 -1
  45. package/dist/session.js +1 -1
  46. package/dist/structured-readiness.d.ts +1 -1
  47. package/package.json +7 -3
  48. package/dist/application-contract.d.ts +0 -22
  49. package/dist/application-contract.js +0 -75
@@ -1,5 +1,5 @@
1
1
  import { type ConnectProblem, type JsonObject, type CollectionOperation } from "@mdbase-dev/connect-protocol";
2
- import { type MdbaseApplicationManifest as MdbaseAppManifest, type MdbaseApplicationCapabilityId as ApplicationCapabilityId } from "./application-contract.js";
2
+ import { type MdbaseApplicationManifest as MdbaseAppManifest, type MdbaseApplicationCapabilityId as ApplicationCapabilityId } from "@mdbase-dev/connect-protocol";
3
3
  import { type ApplicationSessionContext } from "./structured-readiness.js";
4
4
  import type { MdbaseAuthorizationOutcome, MdbaseAuthorizeOptions, MdbaseConnection } from "./connection.js";
5
5
  import type { MdbaseConnectionInfo } from "./connection-types.js";
@@ -1,5 +1,5 @@
1
1
  import { APPLICATION_SETUP_OPERATIONS } from "@mdbase-dev/connect-protocol";
2
- import { declaredOperations, validateAuthorizationSelection } from "./application-contract.js";
2
+ import { declaredOperations, validateAuthorizationSelection } from "@mdbase-dev/connect-protocol";
3
3
  import { accessRequirementSatisfied, applicationReadinessContext, collectionSetupInput, publishedStructuredReadiness, reviewableTypePackAdoptions, verifyStructuredReadiness, verificationKey, verificationValue } from "./structured-readiness.js";
4
4
  import { MdbaseConnectError, connectProblem } from "./errors.js";
5
5
  import { connectFailure, connectSuccess } from "./outcomes.js";
package/dist/async.d.ts CHANGED
@@ -1 +1,7 @@
1
1
  export declare function abortableDelay(milliseconds: number, signal?: AbortSignal): Promise<void>;
2
+ /**
3
+ * Wait before the next change poll. In a hidden browser tab, wait at least
4
+ * {@link HIDDEN_POLL_INTERVAL_MS} instead, but return as soon as the tab
5
+ * becomes visible so a returning user sees current data immediately.
6
+ */
7
+ export declare function pollDelay(milliseconds: number, signal?: AbortSignal): Promise<void>;
package/dist/async.js CHANGED
@@ -17,3 +17,42 @@ export function abortableDelay(milliseconds, signal) {
17
17
  signal?.addEventListener("abort", abort, { once: true });
18
18
  });
19
19
  }
20
+ /** How long `watch` waits between polls while the page is hidden. */
21
+ const HIDDEN_POLL_INTERVAL_MS = 60_000;
22
+ /**
23
+ * Wait before the next change poll. In a hidden browser tab, wait at least
24
+ * {@link HIDDEN_POLL_INTERVAL_MS} instead, but return as soon as the tab
25
+ * becomes visible so a returning user sees current data immediately.
26
+ */
27
+ export function pollDelay(milliseconds, signal) {
28
+ const page = typeof document === "undefined" ? undefined : document;
29
+ if (page?.visibilityState !== "hidden")
30
+ return abortableDelay(milliseconds, signal);
31
+ return new Promise((resolve, reject) => {
32
+ if (signal?.aborted) {
33
+ reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
34
+ return;
35
+ }
36
+ const cleanup = () => {
37
+ clearTimeout(timeout);
38
+ page.removeEventListener("visibilitychange", visible);
39
+ signal?.removeEventListener("abort", abort);
40
+ };
41
+ const visible = () => {
42
+ if (page.visibilityState === "hidden")
43
+ return;
44
+ cleanup();
45
+ resolve();
46
+ };
47
+ const abort = () => {
48
+ cleanup();
49
+ reject(signal?.reason ?? new DOMException("Aborted", "AbortError"));
50
+ };
51
+ const timeout = setTimeout(() => {
52
+ cleanup();
53
+ resolve();
54
+ }, Math.max(milliseconds, HIDDEN_POLL_INTERVAL_MS));
55
+ page.addEventListener("visibilitychange", visible);
56
+ signal?.addEventListener("abort", abort, { once: true });
57
+ });
58
+ }
@@ -11,4 +11,6 @@ interface AuthorizationRefreshOptions {
11
11
  storeTokenResponse(body: any, clientId: string, keyHandle?: string): StoredToken;
12
12
  }
13
13
  export declare function performAuthorizationRefresh(options: AuthorizationRefreshOptions): Promise<StoredToken>;
14
+ /** A refresh refusal that means the stored credential can never work again. */
15
+ export declare function genuineAuthorizationFailure(status: number, code: unknown): boolean;
14
16
  export {};
@@ -30,12 +30,24 @@ export async function performAuthorizationRefresh(options) {
30
30
  const latest = options.currentToken();
31
31
  if (latest?.refreshToken && latest.refreshToken !== attemptedRefreshToken)
32
32
  return latest;
33
+ const code = oauthErrorCode(body) ?? body?.error?.code;
34
+ // Only a refusal of the credential itself ends this connection. A collection
35
+ // being upgraded (409), a suspended account, rate limiting or a server fault
36
+ // leaves the refresh token valid: keep it, so the app recovers by itself.
37
+ if (!genuineAuthorizationFailure(response.status, code)) {
38
+ throw apiError(body, "temporarily_unavailable", "mdbase is temporarily unavailable. Try again in a few minutes.", response.status);
39
+ }
33
40
  if (!options.directCapable(current))
34
41
  options.removeToken(current.keyHandle);
35
- if ((oauthErrorCode(body) ?? body?.error?.code) === "invalid_grant") {
42
+ if (code === "invalid_grant") {
36
43
  throw connectError("authorization_expired", body?.error_description ?? body?.error?.message ?? "Reconnect this application to continue.", { status: response.status });
37
44
  }
38
45
  throw apiError(body, "authorization_expired", "Reconnect this application to continue.", response.status);
39
46
  }
40
47
  return options.storeTokenResponse(body, current.clientId, current.keyHandle);
41
48
  }
49
+ const AUTHORIZATION_FAILURES = new Set(["invalid_grant", "invalid_client", "unauthorized_client", "invalid_token"]);
50
+ /** A refresh refusal that means the stored credential can never work again. */
51
+ export function genuineAuthorizationFailure(status, code) {
52
+ return status === 401 || (typeof code === "string" && AUTHORIZATION_FAILURES.has(code));
53
+ }
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "file": "mdbase-connect.min.js",
3
- "integrity": "sha384-JJDoYra3MuCFJxyktOaw/6TQwPZCx8ZC2YcJhJxOZqXF8xU67X+tyXiEm5KKZwcf"
3
+ "integrity": "sha384-rwS4Cs8c/aA1ZdOgYHyRuQz90zVNe1GLeCYRKxXrHsuo777O2T/z+Bu0Mjpf0tBD"
4
4
  }