@crowdedkingdoms/crowdyjs 15.2.0 → 15.3.0-test.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 +1 -1
- package/README.md +2 -2
- package/dist/binary-relay.d.ts +13 -2
- package/dist/binary-relay.d.ts.map +1 -1
- package/dist/binary-relay.js +13 -2
- package/dist/crowdy-studio/diagnostics.d.ts +14 -1
- package/dist/crowdy-studio/diagnostics.d.ts.map +1 -1
- package/dist/crowdy-studio/index.d.ts +2 -0
- package/dist/crowdy-studio/index.d.ts.map +1 -1
- package/dist/crowdy-studio/index.js +2 -0
- package/dist/crowdy-studio/model-lint-log.d.ts +76 -0
- package/dist/crowdy-studio/model-lint-log.d.ts.map +1 -0
- package/dist/crowdy-studio/model-lint-log.js +93 -0
- package/dist/crowdy-studio/model-lint.d.ts +61 -0
- package/dist/crowdy-studio/model-lint.d.ts.map +1 -0
- package/dist/crowdy-studio/model-lint.js +45 -0
- package/dist/default-origin.d.ts +6 -6
- package/dist/default-origin.d.ts.map +1 -1
- package/dist/default-origin.js +6 -6
- package/dist/domains/discovery.d.ts +1 -1
- package/dist/generated/graphql.d.ts +186 -10
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +50 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/kit/index.d.ts +1 -0
- package/dist/kit/index.d.ts.map +1 -1
- package/dist/kit/index.js +1 -0
- package/dist/kit/notifications.d.ts +45 -0
- package/dist/kit/notifications.d.ts.map +1 -0
- package/dist/kit/notifications.js +67 -0
- package/dist/kit/npcs.d.ts.map +1 -1
- package/dist/kit/social.d.ts.map +1 -1
- package/package.json +1 -1
package/MIGRATION.md
CHANGED
|
@@ -184,7 +184,7 @@ retired:
|
|
|
184
184
|
(`buddyTiers`, `graphqlTiers`, `postgresTiers`) are gone; wallets, budgets
|
|
185
185
|
and transactions stay.
|
|
186
186
|
- **Endpoints**: `managementUrl` and `httpUrl` may now be the SAME origin
|
|
187
|
-
(e.g. `https://ck.test.
|
|
187
|
+
(e.g. `https://ck.test.crowdedkingdoms.com`); configuring both remains supported
|
|
188
188
|
and the two-token model (session vs app-scoped) is unchanged.
|
|
189
189
|
|
|
190
190
|
Everything game-client (auth, users, world/UDP, stores, kit, game model,
|
package/README.md
CHANGED
|
@@ -728,8 +728,8 @@ endpoint; `client.graphql` reaches every surface.)
|
|
|
728
728
|
the environment is not configured, so they are safe to leave in `npm test`.
|
|
729
729
|
|
|
730
730
|
```bash
|
|
731
|
-
CROWDY_HTTP_URL='https://ck.<tier>.
|
|
732
|
-
CROWDY_WS_URL='wss://ck.<tier>.
|
|
731
|
+
CROWDY_HTTP_URL='https://ck.<tier>.crowdedkingdoms.com' \
|
|
732
|
+
CROWDY_WS_URL='wss://ck.<tier>.crowdedkingdoms.com/graphql' \
|
|
733
733
|
CROWDY_OWNER_EMAIL='owner@example.com' \
|
|
734
734
|
CROWDY_TEST_APP_ID='78221653114368' \
|
|
735
735
|
npm run test:e2e
|
package/dist/binary-relay.d.ts
CHANGED
|
@@ -48,8 +48,19 @@ export interface BinaryRelayCallbacks {
|
|
|
48
48
|
* walk an entire fleet's clients somewhere else, which is a much worse outcome
|
|
49
49
|
* than an unbalanced fleet.
|
|
50
50
|
*
|
|
51
|
-
* Compares the last two labels, so `ck-api-4.
|
|
52
|
-
* `ck.prod.
|
|
51
|
+
* Compares the last two labels, so `ck-api-or-4.prod.crowdedkingdoms.com` and
|
|
52
|
+
* `ck.prod.crowdedkingdoms.com` match, and `evil.example.com` does not.
|
|
53
|
+
*
|
|
54
|
+
* TWO LABELS IS COARSER THAN IT LOOKS, AND IT GOT MORE VISIBLE RATHER THAN WORSE.
|
|
55
|
+
* Every tier now sits under one brand root, so "the last two labels" is
|
|
56
|
+
* `crowdedkingdoms.com` for all of them and a redirect could in principle move a prod
|
|
57
|
+
* client onto a dev host. That was equally true before the 2026-08 root migration --
|
|
58
|
+
* the tiers shared a single root then too -- so this is a long-standing property the
|
|
59
|
+
* rename exposed, not one it introduced. It still does the job it was written for:
|
|
60
|
+
* stopping a compromised instance walking clients to an unrelated domain. Narrowing
|
|
61
|
+
* it to the tier is a deliberate change with its own blast radius (it would refuse
|
|
62
|
+
* legitimate cross-datacenter redirects if a tier ever spans roots) and belongs in
|
|
63
|
+
* its own reviewed diff, not in a rename.
|
|
53
64
|
*/
|
|
54
65
|
export declare function isSameEstate(current: string, candidate: string): boolean;
|
|
55
66
|
export interface BinaryRelayConfig {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary-relay.d.ts","sourceRoot":"","sources":["../src/binary-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAgBnD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,IAAI,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACpD,OAAO,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CACN,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,cAAc,GACnE,IAAI,CAAC;IACR;;;OAGG;IACH,aAAa,IAAI,IAAI,CAAC;IACtB;;;;;OAKG;IACH,oBAAoB,CAAC,CAAC,MAAM,EAAE;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,IAAI,CAAC;CACV;AAED
|
|
1
|
+
{"version":3,"file":"binary-relay.d.ts","sourceRoot":"","sources":["../src/binary-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAE1B,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAgBnD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,IAAI,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACpD,OAAO,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CACN,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,cAAc,GACnE,IAAI,CAAC;IACR;;;OAGG;IACH,aAAa,IAAI,IAAI,CAAC;IACtB;;;;;OAKG;IACH,oBAAoB,CAAC,CAAC,MAAM,EAAE;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,IAAI,CAAC;CACV;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAcxE;AAED,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAMD,qBAAa,oBAAoB;IAmB7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAlB5B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,UAAU,CAAK;gBAGrB,MAAM,EAAE,iBAAiB,EACR,SAAS,EAAE,oBAAoB;IASlD,wEAAwE;IACxE,OAAO,IAAI,OAAO;IAQlB,wEAAwE;IACxE,cAAc,IAAI,gBAAgB,GAAG,IAAI;IAIzC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAO5B,UAAU,IAAI,IAAI;IAoBlB,oEAAoE;IACpE,OAAO,IAAI,IAAI;IASf,gEAAgE;IAChE,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAUlC,OAAO,CAAC,IAAI;YAkHE,kBAAkB;IAsChC;;;;;;OAMG;IACH,OAAO,CAAC,wBAAwB;IA2BhC,OAAO,CAAC,UAAU;CAyBnB"}
|
package/dist/binary-relay.js
CHANGED
|
@@ -37,8 +37,19 @@ const UNAVAILABLE_AFTER_RECONNECT_FAILURES = 3;
|
|
|
37
37
|
* walk an entire fleet's clients somewhere else, which is a much worse outcome
|
|
38
38
|
* than an unbalanced fleet.
|
|
39
39
|
*
|
|
40
|
-
* Compares the last two labels, so `ck-api-4.
|
|
41
|
-
* `ck.prod.
|
|
40
|
+
* Compares the last two labels, so `ck-api-or-4.prod.crowdedkingdoms.com` and
|
|
41
|
+
* `ck.prod.crowdedkingdoms.com` match, and `evil.example.com` does not.
|
|
42
|
+
*
|
|
43
|
+
* TWO LABELS IS COARSER THAN IT LOOKS, AND IT GOT MORE VISIBLE RATHER THAN WORSE.
|
|
44
|
+
* Every tier now sits under one brand root, so "the last two labels" is
|
|
45
|
+
* `crowdedkingdoms.com` for all of them and a redirect could in principle move a prod
|
|
46
|
+
* client onto a dev host. That was equally true before the 2026-08 root migration --
|
|
47
|
+
* the tiers shared a single root then too -- so this is a long-standing property the
|
|
48
|
+
* rename exposed, not one it introduced. It still does the job it was written for:
|
|
49
|
+
* stopping a compromised instance walking clients to an unrelated domain. Narrowing
|
|
50
|
+
* it to the tier is a deliberate change with its own blast radius (it would refuse
|
|
51
|
+
* legitimate cross-datacenter redirects if a tier ever spans roots) and belongs in
|
|
52
|
+
* its own reviewed diff, not in a rename.
|
|
42
53
|
*/
|
|
43
54
|
export function isSameEstate(current, candidate) {
|
|
44
55
|
const host = (raw) => {
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { type CrowdyStudioTarget } from './models.js';
|
|
2
2
|
export type CrowdyStudioDiagnosticSeverity = 'error' | 'warning' | 'info' | 'hint';
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Where a diagnostic came from, which is what an editor filters on.
|
|
5
|
+
*
|
|
6
|
+
* `'runtime'` was already in CrowdyCPP's enum and missing here, so the two SDKs disagreed
|
|
7
|
+
* about the shape they both claim to share; adding `'model-lint'` was the moment to close
|
|
8
|
+
* that rather than widen it.
|
|
9
|
+
*
|
|
10
|
+
* `'model-lint'` is the server's `gameModelLint`, and it is a different kind of answer from
|
|
11
|
+
* the other three. Those describe code the developer is editing. This describes whether the
|
|
12
|
+
* app's game model hangs together at all — a container naming a type nobody defined, a
|
|
13
|
+
* function calling one that does not exist — which has no file and no line, and which no
|
|
14
|
+
* amount of reading the open document would reveal.
|
|
15
|
+
*/
|
|
16
|
+
export type CrowdyStudioDiagnosticSource = 'rustc' | 'local-advisory' | 'runtime' | 'model-lint';
|
|
4
17
|
export interface CrowdyStudioDiagnostic {
|
|
5
18
|
target: CrowdyStudioTarget;
|
|
6
19
|
path: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/crowdy-studio/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,8BAA8B,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/crowdy-studio/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,8BAA8B,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,4BAA4B,GACpC,OAAO,GACP,gBAAgB,GAChB,SAAS,GACT,YAAY,CAAC;AAEjB,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,8BAA8B,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,4BAA4B,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,aAAa,EAAE,kBAAkB,GAChC,sBAAsB,EAAE,CA8E1B"}
|
|
@@ -3,6 +3,8 @@ export { mountCrowdyStudio, type CrowdyStudioHandle, type MountCrowdyStudioAgent
|
|
|
3
3
|
export { CrowdyStudioOfflineError, CrowdyStudioRevisionConflictError, cloneCrowdyStudioProject, crowdyStudioFileKey, crowdyStudioFileUri, normalizeCrowdyStudioPath, projectTargets, type CreateCrowdyStudioProjectInput, type ImportCrowdyStudioReferenceFileInput, type CrowdyStudioAtomicFileChange, type CrowdyStudioAtomicPatchInput, type CrowdyStudioAtomicPatchResult, type CrowdyStudioCheckpointFile, type CrowdyStudioCheckpointMetadata, type CrowdyStudioCheckpointRestoreInput, type CrowdyStudioCheckpointRestoreResult, type CrowdyStudioFileRef, type CrowdyStudioPairingPreference, type CrowdyStudioProject, type CrowdyStudioProjectFile, type CrowdyStudioProjectKind, type CrowdyStudioProjectMetadata, type CrowdyStudioProjectProvider, type CrowdyStudioProjectRevision, type CrowdyStudioProjectScope, type CrowdyStudioProjectSummary, type CrowdyStudioReferenceFile, type CrowdyStudioSaveState, type CrowdyStudioSynchronizationProvider, type CrowdyStudioProjectSynchronization, type CrowdyStudioPatchOperation, type CrowdyStudioTarget, type SaveCrowdyStudioLibraryFileInput, type SaveCrowdyStudioProjectInput, } from './models.js';
|
|
4
4
|
export { createCrowdyStudioStarterProject, type CrowdyStudioNewProjectOptions, } from './starter-projects.js';
|
|
5
5
|
export { parseRustcDiagnostics, type CrowdyStudioDiagnostic, type CrowdyStudioDiagnosticSeverity, type CrowdyStudioDiagnosticSource, } from './diagnostics.js';
|
|
6
|
+
export { MODEL_LINT_QUERY, modelLintDiagnostics, modelLintSubjectPath, type CrowdyModelLintFinding, type CrowdyModelLintResult, } from './model-lint.js';
|
|
7
|
+
export { CrowdyModelLintLog, MODEL_REFUSAL_CODES, modelRefusalFrom, type CrowdyModelRefusal, } from './model-lint-log.js';
|
|
6
8
|
export { isCurrentDiagnosticVersion, type MonacoCrowdyStudioEditorOptions, } from './monaco-editor.js';
|
|
7
9
|
export { EMBEDDED_PLATFORM_INDEX, MAX_PLATFORM_CRATES, MAX_PLATFORM_CRATE_FIELD_LENGTH, MAX_PLATFORM_INDEX_BYTES, computePlatformIndexContentHash, loadPlatformIndex, type PlatformCrate, type PlatformIndex, type PlatformSymbol, type PlatformSymbolKind, } from '../live-coding/platform-index.js';
|
|
8
10
|
export { DEFAULT_VFS_LIMITS, VfsLimitError, VirtualFileSystem, offsetAt, type VirtualDocument, type VirtualFileSystemLimits, } from '../live-coding/vfs.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crowdy-studio/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crowdy-studio/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,8 @@ export { mountCrowdyStudio, } from './mount.js';
|
|
|
3
3
|
export { CrowdyStudioOfflineError, CrowdyStudioRevisionConflictError, cloneCrowdyStudioProject, crowdyStudioFileKey, crowdyStudioFileUri, normalizeCrowdyStudioPath, projectTargets, } from './models.js';
|
|
4
4
|
export { createCrowdyStudioStarterProject, } from './starter-projects.js';
|
|
5
5
|
export { parseRustcDiagnostics, } from './diagnostics.js';
|
|
6
|
+
export { MODEL_LINT_QUERY, modelLintDiagnostics, modelLintSubjectPath, } from './model-lint.js';
|
|
7
|
+
export { CrowdyModelLintLog, MODEL_REFUSAL_CODES, modelRefusalFrom, } from './model-lint-log.js';
|
|
6
8
|
export { isCurrentDiagnosticVersion, } from './monaco-editor.js';
|
|
7
9
|
export { EMBEDDED_PLATFORM_INDEX, MAX_PLATFORM_CRATES, MAX_PLATFORM_CRATE_FIELD_LENGTH, MAX_PLATFORM_INDEX_BYTES, computePlatformIndexContentHash, loadPlatformIndex, } from '../live-coding/platform-index.js';
|
|
8
10
|
export { DEFAULT_VFS_LIMITS, VfsLimitError, VirtualFileSystem, offsetAt, } from '../live-coding/vfs.js';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { CrowdyLogger } from '../logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Tell the developer, once, when the server refuses something because the game model is
|
|
4
|
+
* wrong.
|
|
5
|
+
*
|
|
6
|
+
* THIS IS THE HALF THAT WORKS IN A SHIPPED GAME. `gameModelLint` needs `manage_apps`, so a
|
|
7
|
+
* client holding a player token cannot ask whether the app is coherent and never will be
|
|
8
|
+
* able to. What it can see is the server refusing one specific operation, and that turns
|
|
9
|
+
* out to be enough — the refusals carry a code and the facts, so the client can say what
|
|
10
|
+
* happened without being allowed to audit the app.
|
|
11
|
+
*
|
|
12
|
+
* WHY IT MATTERS THAT IT SAYS ANYTHING AT ALL. The case this was built for is a client that
|
|
13
|
+
* called `gameModelEnsureContainer` against a type nobody had defined. The call SUCCEEDED.
|
|
14
|
+
* The container was written, nothing bound to it, and the only trace anywhere was the game's
|
|
15
|
+
* own line — `[GameModel] InvokeAndApply: no container bound for entity F3B8B18E…` — which
|
|
16
|
+
* names a symptom and not one thing about the cause. It read as a permissions fault for
|
|
17
|
+
* most of a day. The server refuses that call now and says why; this is what makes sure the
|
|
18
|
+
* why is not swallowed on the way to the developer.
|
|
19
|
+
*
|
|
20
|
+
* ONCE PER (code, subject), NOT PER OCCURRENCE, and that is not a nicety. These fire on
|
|
21
|
+
* gameplay paths — a bind can be attempted every frame, for every entity — and a warning
|
|
22
|
+
* printed at that rate is indistinguishable from noise. Warnings being ignorable is the
|
|
23
|
+
* root cause of the incident this file exists because of, so reproducing it with better
|
|
24
|
+
* wording would be the one clearly wrong outcome.
|
|
25
|
+
*/
|
|
26
|
+
/** A refusal the server attributes to the app's game model. */
|
|
27
|
+
export interface CrowdyModelRefusal {
|
|
28
|
+
code: string;
|
|
29
|
+
message: string;
|
|
30
|
+
/** The object the refusal is about, for deduplication and for the developer. */
|
|
31
|
+
subject?: string;
|
|
32
|
+
/**
|
|
33
|
+
* For a quarantine: the lint finding that caused it, and what kind of object it is.
|
|
34
|
+
*
|
|
35
|
+
* FIRST-CLASS BECAUSE `reason` IS THE ONLY ACTIONABLE FIELD. Before these existed the
|
|
36
|
+
* server's `quarantineReason` was reachable only by digging through the untyped `detail`
|
|
37
|
+
* bag, so a developer was told their function is quarantined and left to guess which of
|
|
38
|
+
* their lint errors did it. `subject` says which object; this says what to fix.
|
|
39
|
+
*/
|
|
40
|
+
quarantine?: {
|
|
41
|
+
kind?: string;
|
|
42
|
+
reason: string;
|
|
43
|
+
};
|
|
44
|
+
/** Anything else the server named in `extensions`, for the developer to read. */
|
|
45
|
+
detail?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Error codes that mean "your game model is wrong", as opposed to a transient or
|
|
49
|
+
* permissions failure. Keys off `extensions.code`, never the message text.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MODEL_REFUSAL_CODES: Set<string>;
|
|
52
|
+
/** Read a refusal out of a GraphQL error, or null if it is not one of ours. */
|
|
53
|
+
export declare function modelRefusalFrom(error: unknown): CrowdyModelRefusal | null;
|
|
54
|
+
/**
|
|
55
|
+
* Deduplicating sink for model refusals.
|
|
56
|
+
*
|
|
57
|
+
* Holds the set for the life of the process rather than expiring it: the point is to say a
|
|
58
|
+
* thing once, and a TTL would only decide how often to repeat something the developer has
|
|
59
|
+
* already read. A game that runs for hours would repeat it hourly for no gain.
|
|
60
|
+
*/
|
|
61
|
+
export declare class CrowdyModelLintLog {
|
|
62
|
+
private readonly logger;
|
|
63
|
+
private readonly seen;
|
|
64
|
+
private readonly refusals;
|
|
65
|
+
constructor(logger?: CrowdyLogger);
|
|
66
|
+
/**
|
|
67
|
+
* Record a refusal. Returns true when this was the first of its kind, which is also
|
|
68
|
+
* when anything was logged.
|
|
69
|
+
*/
|
|
70
|
+
record(refusal: CrowdyModelRefusal): boolean;
|
|
71
|
+
/** Every distinct refusal seen so far, for an editor panel rather than a log tail. */
|
|
72
|
+
collected(): readonly CrowdyModelRefusal[];
|
|
73
|
+
/** Forget everything, so a reconnect to a repaired app reports afresh. */
|
|
74
|
+
reset(): void;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=model-lint-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-lint-log.d.ts","sourceRoot":"","sources":["../../src/crowdy-studio/model-lint-log.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,aAG9B,CAAC;AAEH,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,IAAI,CA4C1E;AAED;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAIjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;gBAExB,MAAM,GAAE,YAAiB;IAEtD;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO;IAkB5C,sFAAsF;IACtF,SAAS,IAAI,SAAS,kBAAkB,EAAE;IAI1C,0EAA0E;IAC1E,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error codes that mean "your game model is wrong", as opposed to a transient or
|
|
3
|
+
* permissions failure. Keys off `extensions.code`, never the message text.
|
|
4
|
+
*/
|
|
5
|
+
export const MODEL_REFUSAL_CODES = new Set([
|
|
6
|
+
'CONTAINER_TYPE_UNDEFINED',
|
|
7
|
+
'OBJECT_QUARANTINED',
|
|
8
|
+
]);
|
|
9
|
+
/** Read a refusal out of a GraphQL error, or null if it is not one of ours. */
|
|
10
|
+
export function modelRefusalFrom(error) {
|
|
11
|
+
if (typeof error !== 'object' || error === null)
|
|
12
|
+
return null;
|
|
13
|
+
const extensions = error
|
|
14
|
+
.extensions;
|
|
15
|
+
if (!extensions)
|
|
16
|
+
return null;
|
|
17
|
+
const code = extensions.code;
|
|
18
|
+
// A QUARANTINE ON `gameModelInvoke` DOES NOT ARRIVE AS `OBJECT_QUARANTINED`. That entry
|
|
19
|
+
// point is a user-code boundary, so the server rebuilds the error from a
|
|
20
|
+
// { code, blame, retryable } triple and the code becomes USER_CODE_ERROR — while the
|
|
21
|
+
// quarantine fields survive. Recognising the code alone therefore misses the refusal on
|
|
22
|
+
// the single path a player takes, which is where it matters most, so the presence of
|
|
23
|
+
// `quarantineReason` is treated as identifying too.
|
|
24
|
+
const quarantineReason = typeof extensions.quarantineReason === 'string'
|
|
25
|
+
? extensions.quarantineReason
|
|
26
|
+
: undefined;
|
|
27
|
+
const isRefusal = (typeof code === 'string' && MODEL_REFUSAL_CODES.has(code)) ||
|
|
28
|
+
quarantineReason !== undefined;
|
|
29
|
+
if (!isRefusal)
|
|
30
|
+
return null;
|
|
31
|
+
const subject = typeof extensions.typeName === 'string'
|
|
32
|
+
? extensions.typeName
|
|
33
|
+
: typeof extensions.quarantinedName === 'string'
|
|
34
|
+
? extensions.quarantinedName
|
|
35
|
+
: undefined;
|
|
36
|
+
return {
|
|
37
|
+
code: typeof code === 'string' ? code : 'OBJECT_QUARANTINED',
|
|
38
|
+
message: String(error.message ?? code),
|
|
39
|
+
...(subject ? { subject } : {}),
|
|
40
|
+
...(quarantineReason
|
|
41
|
+
? {
|
|
42
|
+
quarantine: {
|
|
43
|
+
...(typeof extensions.quarantinedKind === 'string'
|
|
44
|
+
? { kind: extensions.quarantinedKind }
|
|
45
|
+
: {}),
|
|
46
|
+
reason: quarantineReason,
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
: {}),
|
|
50
|
+
detail: extensions,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Deduplicating sink for model refusals.
|
|
55
|
+
*
|
|
56
|
+
* Holds the set for the life of the process rather than expiring it: the point is to say a
|
|
57
|
+
* thing once, and a TTL would only decide how often to repeat something the developer has
|
|
58
|
+
* already read. A game that runs for hours would repeat it hourly for no gain.
|
|
59
|
+
*/
|
|
60
|
+
export class CrowdyModelLintLog {
|
|
61
|
+
constructor(logger = {}) {
|
|
62
|
+
this.logger = logger;
|
|
63
|
+
this.seen = new Set();
|
|
64
|
+
this.refusals = [];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Record a refusal. Returns true when this was the first of its kind, which is also
|
|
68
|
+
* when anything was logged.
|
|
69
|
+
*/
|
|
70
|
+
record(refusal) {
|
|
71
|
+
const key = `${refusal.code}\u0000${refusal.subject ?? ''}`;
|
|
72
|
+
if (this.seen.has(key))
|
|
73
|
+
return false;
|
|
74
|
+
this.seen.add(key);
|
|
75
|
+
this.refusals.push(refusal);
|
|
76
|
+
// warn, not error: the app is running and the developer is the audience. An
|
|
77
|
+
// error would push a game's own error handling into treating a schema problem
|
|
78
|
+
// as a crash.
|
|
79
|
+
this.logger.warn?.(`[crowdy:model] ${refusal.code}: ${refusal.message}\n` +
|
|
80
|
+
' This is reported once per distinct problem. Call gameModelLint with an ' +
|
|
81
|
+
'app-admin token for everything currently wrong with this app.', refusal.detail);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
/** Every distinct refusal seen so far, for an editor panel rather than a log tail. */
|
|
85
|
+
collected() {
|
|
86
|
+
return this.refusals;
|
|
87
|
+
}
|
|
88
|
+
/** Forget everything, so a reconnect to a repaired app reports afresh. */
|
|
89
|
+
reset() {
|
|
90
|
+
this.seen.clear();
|
|
91
|
+
this.refusals.length = 0;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { CrowdyStudioDiagnostic } from './diagnostics.js';
|
|
2
|
+
import type { CrowdyStudioTarget } from './models.js';
|
|
3
|
+
/**
|
|
4
|
+
* Turn `gameModelLint` findings into the diagnostics an editor already renders.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS IS A MAPPER AND NOT A NEW SURFACE. `CrowdyStudioDiagnostic` already exists on
|
|
7
|
+
* both SDKs, already carries a severity, a code and a message, and CrowdyJS already
|
|
8
|
+
* publishes it over `textDocument/publishDiagnostics` into Monaco. Lint findings are the
|
|
9
|
+
* same kind of thing arriving from a different place, so they become a `source` and reuse
|
|
10
|
+
* the Problems list, the gutter and the filtering for free. A second panel with its own
|
|
11
|
+
* shape would be a second thing to maintain and a second place for a developer to look.
|
|
12
|
+
*
|
|
13
|
+
* WHO CAN CALL THE QUERY THIS CONSUMES. `gameModelLint` is gated on `manage_apps`, so this
|
|
14
|
+
* is for an authoring context — Studio, an engine editor, a dev build signed in as someone
|
|
15
|
+
* who administers the app. A shipped game holding a player token cannot call it and should
|
|
16
|
+
* not be able to: what a player's client gets instead is the server refusing the specific
|
|
17
|
+
* operation, which `recordRefusal` in `./model-lint-log.js` surfaces.
|
|
18
|
+
*
|
|
19
|
+
* THERE IS NO FILE OR LINE, and pretending otherwise would be worse than admitting it.
|
|
20
|
+
* A finding is about a function, a container type or the app, none of which the developer
|
|
21
|
+
* has open in a text editor — the model is authored through the API. So `path` carries the
|
|
22
|
+
* subject and the line is 1: enough for the Problems list to group and label them, without
|
|
23
|
+
* inventing a location that would send a click into the wrong file.
|
|
24
|
+
*/
|
|
25
|
+
/** One finding as `gameModelLint` returns it. */
|
|
26
|
+
export interface CrowdyModelLintFinding {
|
|
27
|
+
code: string;
|
|
28
|
+
severity: 'error' | 'warning';
|
|
29
|
+
subjectKind: string;
|
|
30
|
+
subject: string;
|
|
31
|
+
message: string;
|
|
32
|
+
remedy?: string | null;
|
|
33
|
+
count?: number | null;
|
|
34
|
+
}
|
|
35
|
+
export interface CrowdyModelLintResult {
|
|
36
|
+
appId: string;
|
|
37
|
+
findings: CrowdyModelLintFinding[];
|
|
38
|
+
errorCount: number;
|
|
39
|
+
warningCount: number;
|
|
40
|
+
clean: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The lint query, printed from the generated document rather than written here.
|
|
44
|
+
*
|
|
45
|
+
* IT USED TO BE A TEMPLATE LITERAL, and that made it the one query in this SDK that
|
|
46
|
+
* `check:schema` could not validate: codegen only sees operation documents, so the query
|
|
47
|
+
* asking "is this app's model coherent" was itself unchecked against the schema it targets.
|
|
48
|
+
* `gameModelLint` was not even present in the committed SDL. Printing from
|
|
49
|
+
* `CrowdyModelLintDocument` means the string and the validated document cannot disagree.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MODEL_LINT_QUERY: string;
|
|
52
|
+
/**
|
|
53
|
+
* A stable, readable label for the thing the finding is about.
|
|
54
|
+
*
|
|
55
|
+
* Prefixed with the kind because subjects collide across kinds — an automation and a
|
|
56
|
+
* function may both be called `on_join`, and a Problems list that showed both as `on_join`
|
|
57
|
+
* would be actively misleading about which one is broken.
|
|
58
|
+
*/
|
|
59
|
+
export declare function modelLintSubjectPath(finding: CrowdyModelLintFinding): string;
|
|
60
|
+
export declare function modelLintDiagnostics(result: CrowdyModelLintResult | null | undefined, target?: CrowdyStudioTarget): CrowdyStudioDiagnostic[];
|
|
61
|
+
//# sourceMappingURL=model-lint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-lint.d.ts","sourceRoot":"","sources":["../../src/crowdy-studio/model-lint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EAEvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,iDAAiD;AACjD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,QAAiC,CAAC;AAQ/D;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAE5E;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,EAChD,MAAM,GAAE,kBAAmD,GAC1D,sBAAsB,EAAE,CAkB1B"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { print } from 'graphql';
|
|
2
|
+
import { CrowdyModelLintDocument } from '../generated/graphql.js';
|
|
3
|
+
/**
|
|
4
|
+
* The lint query, printed from the generated document rather than written here.
|
|
5
|
+
*
|
|
6
|
+
* IT USED TO BE A TEMPLATE LITERAL, and that made it the one query in this SDK that
|
|
7
|
+
* `check:schema` could not validate: codegen only sees operation documents, so the query
|
|
8
|
+
* asking "is this app's model coherent" was itself unchecked against the schema it targets.
|
|
9
|
+
* `gameModelLint` was not even present in the committed SDL. Printing from
|
|
10
|
+
* `CrowdyModelLintDocument` means the string and the validated document cannot disagree.
|
|
11
|
+
*/
|
|
12
|
+
export const MODEL_LINT_QUERY = print(CrowdyModelLintDocument);
|
|
13
|
+
function severityOf(finding) {
|
|
14
|
+
return finding.severity === 'error' ? 'error' : 'warning';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A stable, readable label for the thing the finding is about.
|
|
18
|
+
*
|
|
19
|
+
* Prefixed with the kind because subjects collide across kinds — an automation and a
|
|
20
|
+
* function may both be called `on_join`, and a Problems list that showed both as `on_join`
|
|
21
|
+
* would be actively misleading about which one is broken.
|
|
22
|
+
*/
|
|
23
|
+
export function modelLintSubjectPath(finding) {
|
|
24
|
+
return `${finding.subjectKind}/${finding.subject}`;
|
|
25
|
+
}
|
|
26
|
+
export function modelLintDiagnostics(result, target = 'SERVER') {
|
|
27
|
+
if (!result?.findings?.length)
|
|
28
|
+
return [];
|
|
29
|
+
return result.findings.map((finding) => ({
|
|
30
|
+
target,
|
|
31
|
+
path: modelLintSubjectPath(finding),
|
|
32
|
+
line: 1,
|
|
33
|
+
column: 1,
|
|
34
|
+
severity: severityOf(finding),
|
|
35
|
+
// The remedy is joined into the message rather than dropped: an editor's Problems
|
|
36
|
+
// list shows one line per entry and has nowhere else to put it, and a finding a
|
|
37
|
+
// developer cannot act on from where they are reading it is the failure this whole
|
|
38
|
+
// feature exists to fix.
|
|
39
|
+
message: finding.remedy
|
|
40
|
+
? `${finding.message} — ${finding.remedy}`
|
|
41
|
+
: finding.message,
|
|
42
|
+
code: finding.code,
|
|
43
|
+
source: 'model-lint',
|
|
44
|
+
}));
|
|
45
|
+
}
|
package/dist/default-origin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED — do not edit. The operator tooling's
|
|
3
|
-
* `sync-client-origins.mjs --write --tier
|
|
3
|
+
* `sync-client-origins.mjs --write --tier test` writes this file, and
|
|
4
4
|
* `check-sdk-default-origin.mjs` refuses it when it names the wrong tier or a
|
|
5
5
|
* host that declaration does not carry. Regenerate; never hand-edit.
|
|
6
6
|
*
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
* than no default at all. Every fallback this SDK ever removed named a host that
|
|
11
11
|
* was already dead. A generated file plus a gate is what makes this one different.
|
|
12
12
|
*
|
|
13
|
-
* Source: the operator's per-tier public CK API origin declaration, tier '
|
|
13
|
+
* Source: the operator's per-tier public CK API origin declaration, tier 'test'
|
|
14
14
|
*/
|
|
15
15
|
/** The tier this build of the SDK is published for. */
|
|
16
|
-
export declare const CROWDY_DEFAULT_TIER = "
|
|
16
|
+
export declare const CROWDY_DEFAULT_TIER = "test";
|
|
17
17
|
/** The public CK API origin for that tier. */
|
|
18
|
-
export declare const CROWDY_DEFAULT_HTTP_ORIGIN = "https://ck.crowdedkingdoms.com";
|
|
18
|
+
export declare const CROWDY_DEFAULT_HTTP_ORIGIN = "https://ck.test.crowdedkingdoms.com";
|
|
19
19
|
/** The same host over WebSocket. A scheme is composed; a hostname is looked up. */
|
|
20
|
-
export declare const CROWDY_DEFAULT_WS_ORIGIN = "wss://ck.crowdedkingdoms.com";
|
|
20
|
+
export declare const CROWDY_DEFAULT_WS_ORIGIN = "wss://ck.test.crowdedkingdoms.com";
|
|
21
21
|
/** The bare hostname, for callers that need to compare rather than dial. */
|
|
22
|
-
export declare const CROWDY_DEFAULT_HOST = "ck.crowdedkingdoms.com";
|
|
22
|
+
export declare const CROWDY_DEFAULT_HOST = "ck.test.crowdedkingdoms.com";
|
|
23
23
|
//# sourceMappingURL=default-origin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-origin.d.ts","sourceRoot":"","sources":["../src/default-origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,SAAS,CAAC;AAE1C,8CAA8C;AAC9C,eAAO,MAAM,0BAA0B,
|
|
1
|
+
{"version":3,"file":"default-origin.d.ts","sourceRoot":"","sources":["../src/default-origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,SAAS,CAAC;AAE1C,8CAA8C;AAC9C,eAAO,MAAM,0BAA0B,wCAAwC,CAAC;AAEhF,mFAAmF;AACnF,eAAO,MAAM,wBAAwB,sCAAsC,CAAC;AAE5E,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,gCAAgC,CAAC"}
|
package/dist/default-origin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED — do not edit. The operator tooling's
|
|
3
|
-
* `sync-client-origins.mjs --write --tier
|
|
3
|
+
* `sync-client-origins.mjs --write --tier test` writes this file, and
|
|
4
4
|
* `check-sdk-default-origin.mjs` refuses it when it names the wrong tier or a
|
|
5
5
|
* host that declaration does not carry. Regenerate; never hand-edit.
|
|
6
6
|
*
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
* than no default at all. Every fallback this SDK ever removed named a host that
|
|
11
11
|
* was already dead. A generated file plus a gate is what makes this one different.
|
|
12
12
|
*
|
|
13
|
-
* Source: the operator's per-tier public CK API origin declaration, tier '
|
|
13
|
+
* Source: the operator's per-tier public CK API origin declaration, tier 'test'
|
|
14
14
|
*/
|
|
15
15
|
/** The tier this build of the SDK is published for. */
|
|
16
|
-
export const CROWDY_DEFAULT_TIER = '
|
|
16
|
+
export const CROWDY_DEFAULT_TIER = 'test';
|
|
17
17
|
/** The public CK API origin for that tier. */
|
|
18
|
-
export const CROWDY_DEFAULT_HTTP_ORIGIN = 'https://ck.crowdedkingdoms.com';
|
|
18
|
+
export const CROWDY_DEFAULT_HTTP_ORIGIN = 'https://ck.test.crowdedkingdoms.com';
|
|
19
19
|
/** The same host over WebSocket. A scheme is composed; a hostname is looked up. */
|
|
20
|
-
export const CROWDY_DEFAULT_WS_ORIGIN = 'wss://ck.crowdedkingdoms.com';
|
|
20
|
+
export const CROWDY_DEFAULT_WS_ORIGIN = 'wss://ck.test.crowdedkingdoms.com';
|
|
21
21
|
/** The bare hostname, for callers that need to compare rather than dial. */
|
|
22
|
-
export const CROWDY_DEFAULT_HOST = 'ck.crowdedkingdoms.com';
|
|
22
|
+
export const CROWDY_DEFAULT_HOST = 'ck.test.crowdedkingdoms.com';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Where each app lives — the call a client makes BEFORE it authenticates.
|
|
3
3
|
*
|
|
4
|
-
* WHY IT COMES FIRST. `ck.<tier>.
|
|
4
|
+
* WHY IT COMES FIRST. `ck.<tier>.crowdedkingdoms.com` is a multivalue DNS record over every
|
|
5
5
|
* datacenter's load balancer, so a cold client's first request lands wherever DNS
|
|
6
6
|
* pointed it — and roughly half the time that is not the datacenter hosting the app.
|
|
7
7
|
* Authenticating there writes the session in the wrong place and then mints the app
|