@crowdedkingdoms/crowdyjs 8.4.4 → 8.4.6

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/README.md CHANGED
@@ -12,7 +12,7 @@ npm install @crowdedkingdoms/crowdyjs
12
12
 
13
13
  CrowdyJS v4 targets browsers by default and uses native `fetch`, `WebSocket`, `crypto`, `btoa`, and `atob`. Node tools can still use the SDK, but must provide browser-compatible globals when opening realtime connections.
14
14
 
15
- > **Server compatibility:** v5.2+ targets environments on release **v0.1.19 or later** (`cks-game-api >= v0.10.3`, `cks-management-api >= v0.1.70`). The destructive mutations send an `idempotencyKey` argument that older servers don't define. v6.1's `client.gameApps.deleteGrid` additionally requires release **v0.1.33+** (`cks-game-api >= v0.12.3`). The game-model **permission effects** fields (`permissionEffects` on `gameModel.upsertFunction`/`seed`, `permissionEffectsAppliedJson` on events) require a `cks-game-api` build with the `2026-07-17-model-permission-effects` migration (v0.13.11+); older servers reject queries/mutations that include them (omit the fields and everything else keeps working). The **permission-read** surface (the `has_grid_permission`/`grid_at`/`has_chunk_permission` expression builtins the kit's `chunkPermission` locks compile to, and selector `*PermissionWhere` predicates) additionally requires `cks-game-api` **v0.13.12+**.
15
+ > **Server compatibility:** v5.2+ targets environments on release **v0.1.19 or later** (`cks-game-api >= v0.10.3`, `cks-management-api >= v0.1.70`). The destructive mutations send an `idempotencyKey` argument that older servers don't define. v6.1's `client.gameApps.deleteGrid` additionally requires release **v0.1.33+** (`cks-game-api >= v0.12.3`). The game-model **permission effects** fields (`permissionEffects` on `gameModel.upsertFunction`/`seed`, `permissionEffectsAppliedJson` on events) require a `cks-game-api` build with the `2026-07-17-model-permission-effects` migration (v0.13.11+); older servers reject queries/mutations that include them (omit the fields and everything else keeps working). The **permission-read** surface (the `has_grid_permission`/`grid_at`/`has_chunk_permission` expression builtins the kit's `chunkPermission` locks compile to, and selector `*PermissionWhere` predicates) additionally requires `cks-game-api` **v0.13.12+**. Older `cks-game-api` builds report game-model **invoke policy denials** as `FORBIDDEN` GraphQL errors instead of resolving with `success: false`; as of this version the kit's invoke helpers map that error onto the documented `{ success: false, errorMessage }` result, so kit callers behave identically against both server generations.
16
16
 
17
17
  ## Standalone builds and schema refresh
18
18
 
package/dist/index.d.ts CHANGED
@@ -45,7 +45,7 @@
45
45
  * or internal tooling, never an untrusted browser.
46
46
  */
47
47
  /** The published package version. Mirrors `package.json`. */
48
- export declare const VERSION = "8.4.4";
48
+ export declare const VERSION = "8.4.6";
49
49
  export { LbCookieStore } from './lb-cookie-store.js';
50
50
  export { CrowdyClient, createCrowdyClient, type CrowdyClientConfig, } from './crowdy-client.js';
51
51
  export { BrowserLocalStorageTokenStore, SessionStore, type SessionListener, type TokenStore, } from './session.js';
package/dist/index.js CHANGED
@@ -45,7 +45,7 @@
45
45
  * or internal tooling, never an untrusted browser.
46
46
  */
47
47
  /** The published package version. Mirrors `package.json`. */
48
- export const VERSION = '8.4.4';
48
+ export const VERSION = '8.4.6';
49
49
  export { LbCookieStore } from './lb-cookie-store.js';
50
50
  export { CrowdyClient, createCrowdyClient, } from './crowdy-client.js';
51
51
  export { BrowserLocalStorageTokenStore, SessionStore, } from './session.js';
@@ -6,6 +6,12 @@ export type RawInvokeResult = GameModelInvokeMutation['gameModelInvoke'];
6
6
  * A kit invoke outcome: the server's authority/evaluation verdict plus the
7
7
  * parsed return value. Authority denials and expression errors are **not**
8
8
  * exceptions — check {@link success}.
9
+ *
10
+ * Older `cks-game-api` builds violate that contract for policy denials: they
11
+ * throw a GraphQL error with `extensions.code === 'FORBIDDEN'` instead of
12
+ * resolving with `success: false`. {@link kitInvoke} tolerates both server
13
+ * generations by mapping that error onto a denial result — see {@link raw}
14
+ * for how to recognize the mapped case.
9
15
  */
10
16
  export interface KitInvokeResult<T = unknown> {
11
17
  /** `false` when the invoke policy denied the caller or the logic errored (rolled back). */
@@ -14,12 +20,29 @@ export interface KitInvokeResult<T = unknown> {
14
20
  returnValue?: T;
15
21
  /** The server's error message when `success` is false. */
16
22
  errorMessage?: string;
17
- /** The full server result (event id, applied mutations, …). */
23
+ /**
24
+ * The full server result (event id, applied mutations, …).
25
+ *
26
+ * When an older server reported a policy denial as a `FORBIDDEN` GraphQL
27
+ * error (see the interface doc above), no server result exists; the SDK
28
+ * synthesizes a minimal one — `success: false`, `errorMessage` from the
29
+ * GraphQL error, `eventId: ''`, and no applied mutations.
30
+ */
18
31
  raw: RawInvokeResult;
19
32
  }
20
33
  /** Wrap a raw invoke result, parsing the JSON return value. */
21
34
  export declare function toKitInvokeResult<T>(raw: RawInvokeResult): KitInvokeResult<T>;
22
- /** Invoke a model function and wrap the result. */
35
+ /**
36
+ * Invoke a model function and wrap the result.
37
+ *
38
+ * Server-generation tolerance: current `cks-game-api` builds resolve policy
39
+ * denials with `success: false` (the kit contract), but older builds throw a
40
+ * {@link CrowdyGraphQLError} with `extensions.code === 'FORBIDDEN'` instead.
41
+ * This helper catches that specific error and maps it to a
42
+ * `{ success: false, errorMessage }` result with a synthesized {@link
43
+ * KitInvokeResult.raw}, so kit callers see one contract against both server
44
+ * generations. Any other error is rethrown unchanged.
45
+ */
23
46
  export declare function kitInvoke<T = unknown>(gameModel: GameModelAPI, input: {
24
47
  appId: string;
25
48
  functionName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/kit/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,yDAAyD;AACzD,MAAM,MAAM,eAAe,GAAG,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;AAEzE;;;;GAIG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,2FAA2F;IAC3F,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,CAAC;IAChB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,GAAG,EAAE,eAAe,CAAC;CACtB;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,CAe7E;AAED,mDAAmD;AACnD,wBAAsB,SAAS,CAAC,CAAC,GAAG,OAAO,EACzC,SAAS,EAAE,YAAY,EACvB,KAAK,EAAE;IACL,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACA,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAS7B;AAED,gEAAgE;AAChE,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,YAAY,EACvB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAOlC"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/kit/shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,yDAAyD;AACzD,MAAM,MAAM,eAAe,GAAG,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;AAEzE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,2FAA2F;IAC3F,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,CAAC;IAChB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,GAAG,EAAE,eAAe,CAAC;CACtB;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,CAe7E;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAAC,CAAC,GAAG,OAAO,EACzC,SAAS,EAAE,YAAY,EACvB,KAAK,EAAE;IACL,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACA,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CA6B7B;AAED,gEAAgE;AAChE,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,YAAY,EACvB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAOlC"}
@@ -1,3 +1,4 @@
1
+ import { CrowdyGraphQLError } from '../errors.js';
1
2
  /** Wrap a raw invoke result, parsing the JSON return value. */
2
3
  export function toKitInvokeResult(raw) {
3
4
  let returnValue;
@@ -16,15 +17,46 @@ export function toKitInvokeResult(raw) {
16
17
  raw,
17
18
  };
18
19
  }
19
- /** Invoke a model function and wrap the result. */
20
+ /**
21
+ * Invoke a model function and wrap the result.
22
+ *
23
+ * Server-generation tolerance: current `cks-game-api` builds resolve policy
24
+ * denials with `success: false` (the kit contract), but older builds throw a
25
+ * {@link CrowdyGraphQLError} with `extensions.code === 'FORBIDDEN'` instead.
26
+ * This helper catches that specific error and maps it to a
27
+ * `{ success: false, errorMessage }` result with a synthesized {@link
28
+ * KitInvokeResult.raw}, so kit callers see one contract against both server
29
+ * generations. Any other error is rethrown unchanged.
30
+ */
20
31
  export async function kitInvoke(gameModel, input) {
21
- const raw = await gameModel.invoke({
22
- appId: input.appId,
23
- functionName: input.functionName,
24
- selfContainerId: input.selfContainerId,
25
- paramsJson: JSON.stringify(input.params ?? {}),
26
- ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
27
- });
32
+ let raw;
33
+ try {
34
+ raw = await gameModel.invoke({
35
+ appId: input.appId,
36
+ functionName: input.functionName,
37
+ selfContainerId: input.selfContainerId,
38
+ paramsJson: JSON.stringify(input.params ?? {}),
39
+ ...(input.sessionId !== undefined ? { sessionId: input.sessionId } : {}),
40
+ });
41
+ }
42
+ catch (error) {
43
+ if (error instanceof CrowdyGraphQLError && error.code === 'FORBIDDEN') {
44
+ return {
45
+ success: false,
46
+ returnValue: undefined,
47
+ errorMessage: error.message,
48
+ raw: {
49
+ eventId: '',
50
+ functionName: input.functionName,
51
+ success: false,
52
+ returnValueJson: null,
53
+ errorMessage: error.message,
54
+ mutationsApplied: [],
55
+ },
56
+ };
57
+ }
58
+ throw error;
59
+ }
28
60
  return toKitInvokeResult(raw);
29
61
  }
30
62
  /** Read a container's visible properties as a parsed object. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdedkingdoms/crowdyjs",
3
- "version": "8.4.4",
3
+ "version": "8.4.6",
4
4
  "description": "Client SDK for Crowded Kingdoms GraphQL API with UDP proxy support",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",