@crowdedkingdoms/crowdyjs 14.1.0 → 14.2.0-dev.1
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/MIGRATION.md +6 -4
- package/README.md +43 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -1
- package/dist/domains/apps.d.ts +32 -4
- package/dist/domains/apps.d.ts.map +1 -1
- package/dist/domains/apps.js +35 -4
- package/dist/domains/controlPlane.d.ts +1 -1
- package/dist/domains/controlPlane.js +1 -1
- package/dist/domains/gameModel.d.ts +9 -1
- package/dist/domains/gameModel.d.ts.map +1 -1
- package/dist/domains/usage.d.ts +1 -1
- package/dist/domains/usage.js +1 -1
- package/dist/errors.d.ts +87 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +104 -0
- package/dist/generated/graphql.d.ts +354 -9
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +107 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/kit/npcs.d.ts.map +1 -1
- package/dist/kit/shared.d.ts.map +1 -1
- package/dist/kit/shared.js +5 -0
- package/dist/kit/social.d.ts.map +1 -1
- package/package.json +1 -1
package/MIGRATION.md
CHANGED
|
@@ -42,11 +42,13 @@ line and you are done.
|
|
|
42
42
|
An app lives in a single datacenter, and those fields name it. The identity
|
|
43
43
|
client can stay on the shared origin.
|
|
44
44
|
|
|
45
|
-
# CrowdyJS v13 — unified
|
|
45
|
+
# CrowdyJS v13 — unified API (breaking)
|
|
46
46
|
|
|
47
|
-
The platform merged the Management API and Game API into ONE server
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
The platform merged the Management API and Game API into ONE server. v13
|
|
48
|
+
landed on the galaxy database; **gameplay has since moved to PostgreSQL +
|
|
49
|
+
Citus** via `cks-game-api` (galaxy is not the game DB). v13 resyncs the
|
|
50
|
+
committed schema from the unified SDL and removes the surfaces the platform
|
|
51
|
+
retired:
|
|
50
52
|
|
|
51
53
|
- **`client.environments` (and `client.admin.environments`) removed.**
|
|
52
54
|
Dedicated customer environments no longer exist; every app runs on the
|
package/README.md
CHANGED
|
@@ -719,6 +719,49 @@ For any brand-new server field not yet wrapped, `client.graphql.request(...)`
|
|
|
719
719
|
always works. (`client.management` was removed in v14 along with the second
|
|
720
720
|
endpoint; `client.graphql` reaches every surface.)
|
|
721
721
|
|
|
722
|
+
## Maintainers: running the e2e suite
|
|
723
|
+
|
|
724
|
+
`npm run test:e2e` drives a real deployed stack, and the suites self-skip when
|
|
725
|
+
the environment is not configured, so they are safe to leave in `npm test`.
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
CROWDY_HTTP_URL='https://ck.<tier>.cp.cks-env.com' \
|
|
729
|
+
CROWDY_WS_URL='wss://ck.<tier>.cp.cks-env.com/graphql' \
|
|
730
|
+
CROWDY_OWNER_EMAIL='owner@example.com' \
|
|
731
|
+
CROWDY_TEST_APP_ID='78221653114368' \
|
|
732
|
+
npm run test:e2e
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
**`CROWDY_HTTP_URL` is the ENTRY origin, not the gameplay origin.** Point it at
|
|
736
|
+
the shared multivalue name (`ck.<tier>…`), the same one a cold client resolves.
|
|
737
|
+
The harness then does what the SDK is built to do: sign in and mint against the
|
|
738
|
+
entry origin, and build every gameplay client on the `gameApiUrl` /
|
|
739
|
+
`gameApiWsUrl` the mint returns, threading `discoveryUrl` into `realtime` so
|
|
740
|
+
instance loss is recoverable.
|
|
741
|
+
|
|
742
|
+
Do not point it at a single datacenter to "make the tests pass". That was the
|
|
743
|
+
old behaviour and it hid two things. A suite pinned to one datacenter never
|
|
744
|
+
exercises residency at all, so a placement regression cannot fail it. And a
|
|
745
|
+
suite that ran *gameplay* against the shared origin was testing a configuration
|
|
746
|
+
no client is ever in: the origin resolves to every datacenter's load balancer,
|
|
747
|
+
so consecutive requests from one client can be answered by different instances,
|
|
748
|
+
and because the UDP proxy connection is per-instance a subscription opened on
|
|
749
|
+
one and a mutation sent to the other never meet. That produced failures in tests
|
|
750
|
+
as simple as self-echo, which has a single client and cannot have a placement
|
|
751
|
+
problem.
|
|
752
|
+
|
|
753
|
+
`test/e2e/app-residency.test.mjs` is the suite that asserts the contract every
|
|
754
|
+
other suite now depends on — that `discovery.apps()` and `mintAppToken` name the
|
|
755
|
+
same datacenter, and that gameplay works against it. On a single-datacenter
|
|
756
|
+
environment its cross-datacenter assertions self-skip and say so, rather than
|
|
757
|
+
passing quietly.
|
|
758
|
+
|
|
759
|
+
Two endpoint shapes are both correct and are not interchangeable:
|
|
760
|
+
`appDiscovery` answers with the datacenter's load balancer (`ck-<dc>.<zone>`),
|
|
761
|
+
while `mintAppToken` under direct connect hands back one instance
|
|
762
|
+
(`ck-api-<dc>-<n>.<zone>`). They agree on the datacenter, not on the host, which
|
|
763
|
+
is why the mint also returns `discoveryUrl`.
|
|
764
|
+
|
|
722
765
|
## Maintainers: schema artifacts and fixtures
|
|
723
766
|
|
|
724
767
|
CrowdyJS is a standalone public package: a clean clone builds with
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAahD,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzE;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,aAAa;IACxB,yEAAyE;IACzE,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAgB;IAC/C,OAAO,CAAC,iBAAiB,CAAC,CAEM;IAEhC;;;;;;OAMG;gBACS,MAAM,EAAE,mBAAmB,YAAK,EAAE,OAAO,EAAE,YAAY;IAYnE;;;;;;;OAOG;IACH,yBAAyB,CACvB,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAC5D,IAAI;IAIP;;;;OAIG;IACH,WAAW,IAAI,MAAM;IAIrB;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAInC;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,OAAO,CAAC,OAAO,EAAE,UAAU,EAC/B,QAAQ,EAAE,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,EAChD,SAAS,CAAC,EAAE,UAAU,EACtB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACrC,OAAO,CAAC,OAAO,CAAC;IASnB;;;;;;;;;;;;;;;;;;;OAmBG;IACG,KAAK,CAAC,CAAC,GAAG,GAAG,EACjB,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACvC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAO,GACrC,OAAO,CAAC,CAAC,CAAC;IA0Cb,0EAA0E;YAC5D,OAAO;CAyEtB;AAED;;;GAGG;AACH,OAAO,EAAE,aAAa,IAAI,gBAAgB,EAAE,CAAC"}
|
package/dist/client.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { print } from 'graphql';
|
|
10
10
|
import { silentLogger } from './logger.js';
|
|
11
|
-
import { APP_UNAVAILABLE_CODE, CrowdyAppUnavailableError, CrowdyError, CrowdyGraphQLError, CrowdyHttpError, CrowdyNetworkError, CrowdyTimeoutError, } from './errors.js';
|
|
11
|
+
import { APP_UNAVAILABLE_CODE, CrowdyAppUnavailableError, CrowdyError, CrowdyGraphQLError, CrowdyHttpError, CrowdyNetworkError, CrowdyTimeoutError, CrowdyUserCodeFaultError, } from './errors.js';
|
|
12
12
|
import { moveFromErrors } from './datacenter-redirect.js';
|
|
13
13
|
/**
|
|
14
14
|
* Low-level HTTP transport for GraphQL operations against the game or
|
|
@@ -202,6 +202,14 @@ export class GraphQLClient {
|
|
|
202
202
|
if (errors.some((e) => e?.extensions?.code === APP_UNAVAILABLE_CODE)) {
|
|
203
203
|
throw new CrowdyAppUnavailableError(errors);
|
|
204
204
|
}
|
|
205
|
+
// `blame` is present only on a fault the platform has attributed — a failure
|
|
206
|
+
// inside app-authored code, or a refusal on the way into it. Detecting the
|
|
207
|
+
// ATTRIBUTION rather than a list of codes is deliberate: the server can add a
|
|
208
|
+
// code without this line, and every existing catch keeps working because the
|
|
209
|
+
// subclass still extends CrowdyGraphQLError.
|
|
210
|
+
if (errors.some((e) => typeof e?.extensions?.blame === 'string')) {
|
|
211
|
+
throw new CrowdyUserCodeFaultError(errors);
|
|
212
|
+
}
|
|
205
213
|
throw new CrowdyGraphQLError(errors);
|
|
206
214
|
}
|
|
207
215
|
return result.data;
|
package/dist/domains/apps.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { GraphQLClient } from '../client.js';
|
|
2
|
-
import { type AppQuery, type AppBySlugQuery, type MyAppsQuery, type AppsForOrgQuery, type MarketplaceAppsQuery, type MarketplaceAppsQueryVariables, type AppsConnectionQuery, type AppsConnectionQueryVariables, type CreateAppMutation, type UpdateAppMutation, type ArchiveAppMutation, type SetAppVisibilityMutation, type AppCodeAdmissionModeQuery, type AppCodeAdmissionsQuery, type SetAppCodeAdmissionModeMutation, type AdmitAppCodeMutation, type RevokeAppCodeAdmissionMutation, type CreateAppInput, type UpdateAppInput, type AdmitAppCodeInput, type AppVisibility, type CodeAdmissionMode } from '../generated/graphql.js';
|
|
2
|
+
import { type AppQuery, type AppBySlugQuery, type MyAppsQuery, type AppsForOrgQuery, type MarketplaceAppsQuery, type MarketplaceAppsQueryVariables, type AppsConnectionQuery, type AppsConnectionQueryVariables, type CreateAppMutation, type UpdateAppMutation, type ArchiveAppMutation, type SetAppVisibilityMutation, type AppCodeAdmissionModeQuery, type AppCodeAdmissionsQuery, type SetAppCodeAdmissionModeMutation, type AdmitAppCodeMutation, type RevokeAppCodeAdmissionMutation, type PlaceableDatacentersQuery, type CreateAppInput, type UpdateAppInput, type AdmitAppCodeInput, type AppVisibility, type CodeAdmissionMode } from '../generated/graphql.js';
|
|
3
3
|
/**
|
|
4
4
|
* The minimal routing tuple the SDK derives from an `App` row: just enough to
|
|
5
5
|
* decide which game-api endpoint should serve a given app. Returned by
|
|
@@ -172,15 +172,43 @@ export declare class AppsAPI {
|
|
|
172
172
|
* @returns An apps connection.
|
|
173
173
|
*/
|
|
174
174
|
marketplaceConnection(args?: AppsConnectionQueryVariables): Promise<AppsConnectionQuery['appsConnection']>;
|
|
175
|
+
/**
|
|
176
|
+
* The datacenters this deployment can create an app in.
|
|
177
|
+
*
|
|
178
|
+
* Call this before {@link create}. `datacenter` is required and permanent: an
|
|
179
|
+
* app is distributed on its app id, so everything it stores lives in one
|
|
180
|
+
* datacenter for the life of the app, and there is no default that could be
|
|
181
|
+
* right — the instance answering a call on the shared origin is whichever one
|
|
182
|
+
* DNS picked.
|
|
183
|
+
*
|
|
184
|
+
* Offer only entries with `placeable === true`. A datacenter that is known and
|
|
185
|
+
* unplaceable holds no capacity for a new app, and {@link create} will refuse
|
|
186
|
+
* it. An entry that is placeable and reports `serving: 'NOT_SERVING'` will hold
|
|
187
|
+
* the app fine; its players cannot connect until an instance is back.
|
|
188
|
+
*
|
|
189
|
+
* An EMPTY `datacenters` list means no topology has been pushed to this
|
|
190
|
+
* deployment and app creation is unavailable — an operator problem, not a
|
|
191
|
+
* caller one. `placementEnforced: false` is a single-node deployment (a
|
|
192
|
+
* developer machine), where the one entry returned is a formality.
|
|
193
|
+
*
|
|
194
|
+
* @returns The choices, plus `placementEnforced` and `servedBy`.
|
|
195
|
+
* @throws {CrowdyGraphQLError} `UNAUTHENTICATED` without a session.
|
|
196
|
+
*/
|
|
197
|
+
placeableDatacenters(): Promise<PlaceableDatacentersQuery['placeableDatacenters']>;
|
|
175
198
|
/**
|
|
176
199
|
* Create a new app under an organization. Requires the `manage_apps` org
|
|
177
200
|
* permission. The new app auto-provisions an open-by-default access tier.
|
|
178
201
|
*
|
|
179
|
-
* @param input - {@link CreateAppInput}: `orgId`, `name`, `slug`,
|
|
180
|
-
* `description`/`visibility`/`metadata`.
|
|
202
|
+
* @param input - {@link CreateAppInput}: `orgId`, `name`, `slug`,
|
|
203
|
+
* `datacenter`, optional `description`/`visibility`/`metadata`.
|
|
204
|
+
* `datacenter` is REQUIRED and permanent — read the accepted codes from
|
|
205
|
+
* {@link placeableDatacenters} rather than hard-coding one, since they are a
|
|
206
|
+
* property of the deployment.
|
|
181
207
|
* @returns The created {@link App}.
|
|
182
208
|
* @throws {CrowdyGraphQLError} `FORBIDDEN`/`SCOPE_MISSING` without
|
|
183
|
-
* `manage_apps`, or `BAD_USER_INPUT` (e.g. duplicate slug
|
|
209
|
+
* `manage_apps`, or `BAD_USER_INPUT` (e.g. duplicate slug, or a datacenter
|
|
210
|
+
* this deployment cannot place an app in — the message names the ones it
|
|
211
|
+
* can).
|
|
184
212
|
*/
|
|
185
213
|
create(input: CreateAppInput): Promise<CreateAppMutation['createApp']>;
|
|
186
214
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/domains/apps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/domains/apps.ts"],"names":[],"mappings":"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"}
|
package/dist/domains/apps.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppDocument, AppBySlugDocument, MyAppsDocument, AppsForOrgDocument, MarketplaceAppsDocument, AppsConnectionDocument, CreateAppDocument, UpdateAppDocument, ArchiveAppDocument, SetAppVisibilityDocument, AppCodeAdmissionModeDocument, AppCodeAdmissionsDocument, SetAppCodeAdmissionModeDocument, AdmitAppCodeDocument, RevokeAppCodeAdmissionDocument, } from '../generated/graphql.js';
|
|
1
|
+
import { AppDocument, AppBySlugDocument, MyAppsDocument, AppsForOrgDocument, MarketplaceAppsDocument, AppsConnectionDocument, CreateAppDocument, UpdateAppDocument, ArchiveAppDocument, SetAppVisibilityDocument, AppCodeAdmissionModeDocument, AppCodeAdmissionsDocument, SetAppCodeAdmissionModeDocument, AdmitAppCodeDocument, RevokeAppCodeAdmissionDocument, PlaceableDatacentersDocument, } from '../generated/graphql.js';
|
|
2
2
|
function appRouteFromAppRow(row) {
|
|
3
3
|
if (!row || typeof row !== 'object')
|
|
4
4
|
return null;
|
|
@@ -204,15 +204,46 @@ export class AppsAPI {
|
|
|
204
204
|
const data = await this.api.request(AppsConnectionDocument, args);
|
|
205
205
|
return data.appsConnection;
|
|
206
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* The datacenters this deployment can create an app in.
|
|
209
|
+
*
|
|
210
|
+
* Call this before {@link create}. `datacenter` is required and permanent: an
|
|
211
|
+
* app is distributed on its app id, so everything it stores lives in one
|
|
212
|
+
* datacenter for the life of the app, and there is no default that could be
|
|
213
|
+
* right — the instance answering a call on the shared origin is whichever one
|
|
214
|
+
* DNS picked.
|
|
215
|
+
*
|
|
216
|
+
* Offer only entries with `placeable === true`. A datacenter that is known and
|
|
217
|
+
* unplaceable holds no capacity for a new app, and {@link create} will refuse
|
|
218
|
+
* it. An entry that is placeable and reports `serving: 'NOT_SERVING'` will hold
|
|
219
|
+
* the app fine; its players cannot connect until an instance is back.
|
|
220
|
+
*
|
|
221
|
+
* An EMPTY `datacenters` list means no topology has been pushed to this
|
|
222
|
+
* deployment and app creation is unavailable — an operator problem, not a
|
|
223
|
+
* caller one. `placementEnforced: false` is a single-node deployment (a
|
|
224
|
+
* developer machine), where the one entry returned is a formality.
|
|
225
|
+
*
|
|
226
|
+
* @returns The choices, plus `placementEnforced` and `servedBy`.
|
|
227
|
+
* @throws {CrowdyGraphQLError} `UNAUTHENTICATED` without a session.
|
|
228
|
+
*/
|
|
229
|
+
async placeableDatacenters() {
|
|
230
|
+
const data = await this.api.request(PlaceableDatacentersDocument, {});
|
|
231
|
+
return data.placeableDatacenters;
|
|
232
|
+
}
|
|
207
233
|
/**
|
|
208
234
|
* Create a new app under an organization. Requires the `manage_apps` org
|
|
209
235
|
* permission. The new app auto-provisions an open-by-default access tier.
|
|
210
236
|
*
|
|
211
|
-
* @param input - {@link CreateAppInput}: `orgId`, `name`, `slug`,
|
|
212
|
-
* `description`/`visibility`/`metadata`.
|
|
237
|
+
* @param input - {@link CreateAppInput}: `orgId`, `name`, `slug`,
|
|
238
|
+
* `datacenter`, optional `description`/`visibility`/`metadata`.
|
|
239
|
+
* `datacenter` is REQUIRED and permanent — read the accepted codes from
|
|
240
|
+
* {@link placeableDatacenters} rather than hard-coding one, since they are a
|
|
241
|
+
* property of the deployment.
|
|
213
242
|
* @returns The created {@link App}.
|
|
214
243
|
* @throws {CrowdyGraphQLError} `FORBIDDEN`/`SCOPE_MISSING` without
|
|
215
|
-
* `manage_apps`, or `BAD_USER_INPUT` (e.g. duplicate slug
|
|
244
|
+
* `manage_apps`, or `BAD_USER_INPUT` (e.g. duplicate slug, or a datacenter
|
|
245
|
+
* this deployment cannot place an app in — the message names the ones it
|
|
246
|
+
* can).
|
|
216
247
|
*/
|
|
217
248
|
async create(input) {
|
|
218
249
|
const data = await this.api.request(CreateAppDocument, { input });
|
|
@@ -3,7 +3,7 @@ import { type CpComputePlatformCeilingsQuery, type CpSetComputePlatformCeilingsM
|
|
|
3
3
|
/**
|
|
4
4
|
* Operator (platform-policy) surface — exposed as `client.operator`.
|
|
5
5
|
*
|
|
6
|
-
* As of the unified
|
|
6
|
+
* As of the v13 unified API this surface is reduced to the platform-wide
|
|
7
7
|
* compute ceilings: dedicated customer environments were retired, and the
|
|
8
8
|
* infrastructure control plane (environments, change orders, secrets, release
|
|
9
9
|
* management, audit) moved to the separate infra-control-plane service with
|
|
@@ -2,7 +2,7 @@ import { CpComputePlatformCeilingsDocument, CpSetComputePlatformCeilingsDocument
|
|
|
2
2
|
/**
|
|
3
3
|
* Operator (platform-policy) surface — exposed as `client.operator`.
|
|
4
4
|
*
|
|
5
|
-
* As of the unified
|
|
5
|
+
* As of the v13 unified API this surface is reduced to the platform-wide
|
|
6
6
|
* compute ceilings: dedicated customer environments were retired, and the
|
|
7
7
|
* infrastructure control plane (environments, change orders, secrets, release
|
|
8
8
|
* management, audit) moved to the separate infra-control-plane service with
|
|
@@ -73,7 +73,15 @@ import { type GameModelCreateSessionMutation, type GameModelCreateSessionMutatio
|
|
|
73
73
|
* selfContainerId,
|
|
74
74
|
* paramsJson: JSON.stringify({ amount: 10 }),
|
|
75
75
|
* });
|
|
76
|
-
*
|
|
76
|
+
* // Authority and evaluation failures do NOT throw — they come back in band, because
|
|
77
|
+
* // the result still carries an event id and any writes that did apply.
|
|
78
|
+
* const fault = playerFaultOf(result);
|
|
79
|
+
* if (fault) {
|
|
80
|
+
* // `fault.blame` is the platform's attribution: AUTHOR (this app's code), PLATFORM
|
|
81
|
+
* // (ours) or BUDGET (an allowance). Choose your own wording — the server no longer
|
|
82
|
+
* // sends engine text, deliberately.
|
|
83
|
+
* if (fault.retryable) scheduleRetry();
|
|
84
|
+
* }
|
|
77
85
|
* ```
|
|
78
86
|
*/
|
|
79
87
|
/** One container-change push from {@link GameModelAPI.containerChanged}. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gameModel.d.ts","sourceRoot":"","sources":["../../src/domains/gameModel.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"gameModel.d.ts","sourceRoot":"","sources":["../../src/domains/gameModel.ts"],"names":[],"mappings":"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"}
|
package/dist/domains/usage.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { type AppGraphqlOperationsQuery, type AppUsageSummaryQuery, type PlayerP
|
|
|
9
9
|
* counters are returned as string counters because they can exceed the 32-bit
|
|
10
10
|
* Int range. `BigInt` ids are decimal strings.
|
|
11
11
|
*
|
|
12
|
-
* As of the unified
|
|
12
|
+
* As of the v13 unified API the per-environment rollups
|
|
13
13
|
* (environmentSummary/orgByEnvironment/environmentByApp) were retired with
|
|
14
14
|
* dedicated customer environments — usage is org/app-scoped.
|
|
15
15
|
*
|
package/dist/domains/usage.js
CHANGED
|
@@ -8,7 +8,7 @@ import { AppGraphqlOperationsDocument, AppUsageSummaryDocument, PlayerPulseDocum
|
|
|
8
8
|
* counters are returned as string counters because they can exceed the 32-bit
|
|
9
9
|
* Int range. `BigInt` ids are decimal strings.
|
|
10
10
|
*
|
|
11
|
-
* As of the unified
|
|
11
|
+
* As of the v13 unified API the per-environment rollups
|
|
12
12
|
* (environmentSummary/orgByEnvironment/environmentByApp) were retired with
|
|
13
13
|
* dedicated customer environments — usage is org/app-scoped.
|
|
14
14
|
*
|
package/dist/errors.d.ts
CHANGED
|
@@ -158,6 +158,93 @@ export declare class CrowdyAppUnavailableError extends CrowdyGraphQLError {
|
|
|
158
158
|
*/
|
|
159
159
|
get retryable(): boolean;
|
|
160
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* Whose problem a failure is, as the platform attributes it.
|
|
163
|
+
*
|
|
164
|
+
* The one question a game cannot answer for itself: from inside a client there is no way
|
|
165
|
+
* to tell "your function is too slow" from "we were busy and never ran it" from "this app
|
|
166
|
+
* is out of budget", and until the server started saying so, all three arrived as the
|
|
167
|
+
* same sentence. Presentation is still yours — this says only whose fault it was.
|
|
168
|
+
*/
|
|
169
|
+
export type CrowdyFaultBlame = 'PLATFORM' | 'AUTHOR' | 'BUDGET';
|
|
170
|
+
/**
|
|
171
|
+
* The stable reason a call into app-authored code failed.
|
|
172
|
+
*
|
|
173
|
+
* Deliberately coarse. It never names an engine, a module, a function or a limit,
|
|
174
|
+
* because those are the app developer's business and not the player's — the developer
|
|
175
|
+
* reads the full detail in the Crowdy console. Treat it as an open union: the server may
|
|
176
|
+
* add a code, and a client that switches on it should have a default branch.
|
|
177
|
+
*/
|
|
178
|
+
export type CrowdyFaultCode = 'USER_CODE_ERROR' | 'USER_CODE_TOO_SLOW' | 'USER_CODE_LIMIT_EXCEEDED' | 'PLATFORM_BUSY' | 'PLATFORM_ERROR' | 'BUDGET_EXCEEDED' | 'RATE_LIMITED' | 'QUOTA_EXHAUSTED' | 'TEMPORARILY_DISABLED' | 'INVALID_REQUEST' | 'NOT_ALLOWED' | 'NOT_FOUND' | 'UNAUTHENTICATED' | 'WRONG_DATACENTER' | 'APP_UNAVAILABLE' | (string & {});
|
|
179
|
+
/** What the platform says about a failure, in the only vocabulary a player is shown. */
|
|
180
|
+
export interface CrowdyPlayerFault {
|
|
181
|
+
/** A stable, enumerated reason. Branch on this, never on a message. */
|
|
182
|
+
code: CrowdyFaultCode;
|
|
183
|
+
/** Whose problem it is. */
|
|
184
|
+
blame: CrowdyFaultBlame;
|
|
185
|
+
/** Whether repeating the identical call could succeed with nothing else changing. */
|
|
186
|
+
retryable: boolean;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* A call into code the platform did not write failed, and the platform has said whose
|
|
190
|
+
* fault it was.
|
|
191
|
+
*
|
|
192
|
+
* WHY THIS EXISTS RATHER THAN A MESSAGE. Until 2026-08-11 a failure inside an app's own
|
|
193
|
+
* function reached the client as the server's internal text — `Evaluation timed out` was
|
|
194
|
+
* returned to players of every app for four days while the real cause was a platform
|
|
195
|
+
* query taking 1.2 seconds. A game rendering that string told its players their own game
|
|
196
|
+
* was broken, on the platform's behalf, in the platform's words. Nothing on the wire
|
|
197
|
+
* distinguished the three cases, so no game could have done better.
|
|
198
|
+
*
|
|
199
|
+
* Now the server attributes blame and the game decides what to render. Nothing in
|
|
200
|
+
* {@link message} is written by the app's code or by an engine; it is a platform-authored
|
|
201
|
+
* sentence, safe to show as-is, and you are expected to replace it with your own.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```ts
|
|
205
|
+
* try {
|
|
206
|
+
* await client.compute.invoke({ appId, moduleName: 'combat', exportName: 'hit' });
|
|
207
|
+
* } catch (err) {
|
|
208
|
+
* const fault = playerFaultOf(err);
|
|
209
|
+
* if (!fault) throw err;
|
|
210
|
+
* if (fault.blame === 'PLATFORM' && fault.retryable) return retryLater();
|
|
211
|
+
* if (fault.blame === 'BUDGET') return showBanner('The arena is busy — one moment.');
|
|
212
|
+
* return showBanner('That move did not work.'); // AUTHOR: our bug, our wording
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
export declare class CrowdyUserCodeFaultError extends CrowdyGraphQLError {
|
|
217
|
+
/** The platform's attribution: `{ code, blame, retryable }`. */
|
|
218
|
+
get fault(): CrowdyPlayerFault;
|
|
219
|
+
/** Whose problem this is. Shorthand for `fault.blame`. */
|
|
220
|
+
get blame(): CrowdyFaultBlame;
|
|
221
|
+
/** Whether repeating the identical call could succeed. Shorthand for `fault.retryable`. */
|
|
222
|
+
get retryable(): boolean;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Read the platform's attribution from EITHER carrier, so a game branches once.
|
|
226
|
+
*
|
|
227
|
+
* There are two, and the split is the server's rather than a wart of this SDK.
|
|
228
|
+
* `computeInvoke` and `playerComputeInvoke` FAIL — they throw, and the fault arrives in
|
|
229
|
+
* the GraphQL error's extensions. `gameModelInvoke` RETURNS — a denial or an evaluation
|
|
230
|
+
* failure is a gameplay verdict that still carries an event id and any writes that did
|
|
231
|
+
* apply, so it comes back as `success: false` with a `fault` field. Forcing either into
|
|
232
|
+
* the other's shape would lose something real, so this function accepts both and gives
|
|
233
|
+
* you one thing to switch on.
|
|
234
|
+
*
|
|
235
|
+
* Returns `null` when there is no fault: a successful result, or an error that is not an
|
|
236
|
+
* attributed one (a network drop, a timeout, an ordinary validation error elsewhere in
|
|
237
|
+
* the API). `null` means "this is not a question about whose code failed" — keep
|
|
238
|
+
* handling it the way you already do.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* const result = await client.gameModel.invoke({ appId, functionName, selfContainerId });
|
|
243
|
+
* const fault = playerFaultOf(result);
|
|
244
|
+
* if (fault?.retryable) scheduleRetry();
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
export declare function playerFaultOf(value: unknown): CrowdyPlayerFault | null;
|
|
161
248
|
/**
|
|
162
249
|
* A network-level failure before any HTTP response was received: DNS failure,
|
|
163
250
|
* TLS error, connection refused, or an aborted `fetch`. Generally retryable
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,iFAAiF;AACjF,MAAM,WAAW,yBAAyB;IACxC,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,SAAS,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC/B,2EAA2E;IAC3E,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACpC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,oEAAoE;AACpE,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,KAAK;IACpC,yDAAyD;IACzD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEb,OAAO,EAAE,kBAAkB;CAKxC;AAED;;;;;;GAMG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,wCAAwC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAKzC;AAED;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,SAAQ,WAAW;IACjD,oEAAoE;IACpE,QAAQ,CAAC,aAAa,EAAE,yBAAyB,EAAE,CAAC;gBAExC,MAAM,EAAE,yBAAyB,EAAE;IAK/C;;;;;;OAMG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IAED;;;;OAIG;IACH,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAEpD;CACF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD,0EAA0E;AAC1E,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,yBAA0B,SAAQ,kBAAkB;IAC/D,8DAA8D;IAC9D,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAG9B;IAED;;;OAGG;IACH,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAGtC;IAED;;;;;OAKG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;CACF;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,WAAW;gBACrC,KAAK,EAAE,OAAO;CAG3B;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,WAAW;gBACrC,SAAS,EAAE,MAAM;CAG9B;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAKnG;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;CAAG"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js
CHANGED
|
@@ -151,6 +151,110 @@ export class CrowdyAppUnavailableError extends CrowdyGraphQLError {
|
|
|
151
151
|
return this.extensions?.retryable !== false;
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* A call into code the platform did not write failed, and the platform has said whose
|
|
156
|
+
* fault it was.
|
|
157
|
+
*
|
|
158
|
+
* WHY THIS EXISTS RATHER THAN A MESSAGE. Until 2026-08-11 a failure inside an app's own
|
|
159
|
+
* function reached the client as the server's internal text — `Evaluation timed out` was
|
|
160
|
+
* returned to players of every app for four days while the real cause was a platform
|
|
161
|
+
* query taking 1.2 seconds. A game rendering that string told its players their own game
|
|
162
|
+
* was broken, on the platform's behalf, in the platform's words. Nothing on the wire
|
|
163
|
+
* distinguished the three cases, so no game could have done better.
|
|
164
|
+
*
|
|
165
|
+
* Now the server attributes blame and the game decides what to render. Nothing in
|
|
166
|
+
* {@link message} is written by the app's code or by an engine; it is a platform-authored
|
|
167
|
+
* sentence, safe to show as-is, and you are expected to replace it with your own.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* try {
|
|
172
|
+
* await client.compute.invoke({ appId, moduleName: 'combat', exportName: 'hit' });
|
|
173
|
+
* } catch (err) {
|
|
174
|
+
* const fault = playerFaultOf(err);
|
|
175
|
+
* if (!fault) throw err;
|
|
176
|
+
* if (fault.blame === 'PLATFORM' && fault.retryable) return retryLater();
|
|
177
|
+
* if (fault.blame === 'BUDGET') return showBanner('The arena is busy — one moment.');
|
|
178
|
+
* return showBanner('That move did not work.'); // AUTHOR: our bug, our wording
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*/
|
|
182
|
+
export class CrowdyUserCodeFaultError extends CrowdyGraphQLError {
|
|
183
|
+
/** The platform's attribution: `{ code, blame, retryable }`. */
|
|
184
|
+
get fault() {
|
|
185
|
+
const extensions = this.extensions ?? {};
|
|
186
|
+
return {
|
|
187
|
+
code: extensions.code ?? 'PLATFORM_ERROR',
|
|
188
|
+
blame: extensions.blame ?? 'PLATFORM',
|
|
189
|
+
// Absent means "we did not say", and the safe reading of that is the one that does
|
|
190
|
+
// not send a client into a loop.
|
|
191
|
+
retryable: extensions.retryable === true,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/** Whose problem this is. Shorthand for `fault.blame`. */
|
|
195
|
+
get blame() {
|
|
196
|
+
return this.fault.blame;
|
|
197
|
+
}
|
|
198
|
+
/** Whether repeating the identical call could succeed. Shorthand for `fault.retryable`. */
|
|
199
|
+
get retryable() {
|
|
200
|
+
return this.fault.retryable;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** Extensions carry `blame` only for a fault the platform has attributed. */
|
|
204
|
+
function faultFromExtensions(extensions) {
|
|
205
|
+
if (!extensions || typeof extensions.blame !== 'string')
|
|
206
|
+
return null;
|
|
207
|
+
return {
|
|
208
|
+
code: extensions.code ?? 'PLATFORM_ERROR',
|
|
209
|
+
blame: extensions.blame,
|
|
210
|
+
retryable: extensions.retryable === true,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Read the platform's attribution from EITHER carrier, so a game branches once.
|
|
215
|
+
*
|
|
216
|
+
* There are two, and the split is the server's rather than a wart of this SDK.
|
|
217
|
+
* `computeInvoke` and `playerComputeInvoke` FAIL — they throw, and the fault arrives in
|
|
218
|
+
* the GraphQL error's extensions. `gameModelInvoke` RETURNS — a denial or an evaluation
|
|
219
|
+
* failure is a gameplay verdict that still carries an event id and any writes that did
|
|
220
|
+
* apply, so it comes back as `success: false` with a `fault` field. Forcing either into
|
|
221
|
+
* the other's shape would lose something real, so this function accepts both and gives
|
|
222
|
+
* you one thing to switch on.
|
|
223
|
+
*
|
|
224
|
+
* Returns `null` when there is no fault: a successful result, or an error that is not an
|
|
225
|
+
* attributed one (a network drop, a timeout, an ordinary validation error elsewhere in
|
|
226
|
+
* the API). `null` means "this is not a question about whose code failed" — keep
|
|
227
|
+
* handling it the way you already do.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```ts
|
|
231
|
+
* const result = await client.gameModel.invoke({ appId, functionName, selfContainerId });
|
|
232
|
+
* const fault = playerFaultOf(result);
|
|
233
|
+
* if (fault?.retryable) scheduleRetry();
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
export function playerFaultOf(value) {
|
|
237
|
+
if (!value || typeof value !== 'object')
|
|
238
|
+
return null;
|
|
239
|
+
if (value instanceof CrowdyGraphQLError) {
|
|
240
|
+
return faultFromExtensions(value.extensions);
|
|
241
|
+
}
|
|
242
|
+
// The in-band carrier: an invoke result that reports its own failure.
|
|
243
|
+
const result = value;
|
|
244
|
+
const fault = result.fault;
|
|
245
|
+
if (fault && typeof fault.blame === 'string') {
|
|
246
|
+
return {
|
|
247
|
+
code: fault.code ?? 'PLATFORM_ERROR',
|
|
248
|
+
blame: fault.blame,
|
|
249
|
+
retryable: fault.retryable === true,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
// A raw GraphQL error payload, e.g. one entry pulled out of `graphqlErrors`.
|
|
253
|
+
const payload = value;
|
|
254
|
+
if (payload.extensions)
|
|
255
|
+
return faultFromExtensions(payload.extensions);
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
154
258
|
/**
|
|
155
259
|
* A network-level failure before any HTTP response was received: DNS failure,
|
|
156
260
|
* TLS error, connection refused, or an aborted `fetch`. Generally retryable
|