@anweather/game-plugin-ssdk 1.9.0 → 1.10.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/dist-cjs/runtime/blobClient.js +81 -0
- package/dist-cjs/runtime/index.js +7 -1
- package/dist-cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist-es/runtime/blobClient.js +74 -0
- package/dist-es/runtime/index.js +1 -0
- package/dist-es/tsconfig.es.tsbuildinfo +1 -1
- package/dist-types/runtime/blobClient.d.ts +84 -0
- package/dist-types/runtime/index.d.ts +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** `save:{id}`, `player:{id}` or `world:{uuid}` -- see the model's doc. */
|
|
2
|
+
export type BlobOwnerKey = `save:${string}` | `player:${string}` | `world:${string}`;
|
|
3
|
+
export declare const blobOwner: {
|
|
4
|
+
save: (saveFileId: string) => BlobOwnerKey;
|
|
5
|
+
player: (participantId: string) => BlobOwnerKey;
|
|
6
|
+
world: (worldId: string) => BlobOwnerKey;
|
|
7
|
+
};
|
|
8
|
+
export interface BlobClientOptions {
|
|
9
|
+
/** The platform's base URL, e.g. http://platform:8080. */
|
|
10
|
+
platformUrl: string;
|
|
11
|
+
gameType: string;
|
|
12
|
+
/** The token this plugin registered with; sent as X-Plugin-Auth. */
|
|
13
|
+
authToken: string | undefined;
|
|
14
|
+
/** Per-request timeout. Keep it well inside ApplyMove's own RPC budget
|
|
15
|
+
* when calling from a move. Default 5000. */
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
fetchImpl?: typeof fetch;
|
|
18
|
+
}
|
|
19
|
+
export interface Blob<T = unknown> {
|
|
20
|
+
/** Absent when the blob doesn't exist. */
|
|
21
|
+
value?: T;
|
|
22
|
+
/** 0 when the blob doesn't exist -- the expectedVersion a create needs. */
|
|
23
|
+
version: number;
|
|
24
|
+
sizeBytes: number;
|
|
25
|
+
updatedAt?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface BlobItem<T = unknown> extends Blob<T> {
|
|
28
|
+
key: string;
|
|
29
|
+
}
|
|
30
|
+
export interface BlobInfo {
|
|
31
|
+
key: string;
|
|
32
|
+
version: number;
|
|
33
|
+
sizeBytes: number;
|
|
34
|
+
updatedAt: string;
|
|
35
|
+
}
|
|
36
|
+
export interface BlobWrite {
|
|
37
|
+
key: string;
|
|
38
|
+
value: unknown;
|
|
39
|
+
/** The version the write is based on; 0 = only if absent. */
|
|
40
|
+
expectedVersion: number;
|
|
41
|
+
}
|
|
42
|
+
export type BlobErrorType = "VersionConflict" | "BlobTooLarge" | "BlobQuotaExceeded" | "BlobOwnerNotFound" | "InvalidBlobRequest" | "PluginUnauthorized";
|
|
43
|
+
/** A refusal from the store. `details` is the error body: for
|
|
44
|
+
* VersionConflict `{key, expectedVersion, currentVersion}`, for
|
|
45
|
+
* BlobTooLarge `{key, sizeBytes, limitBytes}`, and so on -- see the
|
|
46
|
+
* model. Any other failure (network, timeout, a 5xx) is a plain Error. */
|
|
47
|
+
export declare class BlobStoreError extends Error {
|
|
48
|
+
readonly type: BlobErrorType;
|
|
49
|
+
readonly status: number;
|
|
50
|
+
readonly details: Record<string, unknown>;
|
|
51
|
+
constructor(type: BlobErrorType, status: number, details: Record<string, unknown>);
|
|
52
|
+
}
|
|
53
|
+
export declare function isVersionConflict(e: unknown): e is BlobStoreError;
|
|
54
|
+
export interface BlobClient {
|
|
55
|
+
get<T = unknown>(owner: BlobOwnerKey, key: string): Promise<Blob<T>>;
|
|
56
|
+
put(owner: BlobOwnerKey, key: string, value: unknown, expectedVersion: number): Promise<{
|
|
57
|
+
version: number;
|
|
58
|
+
sizeBytes: number;
|
|
59
|
+
}>;
|
|
60
|
+
/** Without expectedVersion the delete is unconditional. */
|
|
61
|
+
delete(owner: BlobOwnerKey, key: string, expectedVersion?: number): Promise<{
|
|
62
|
+
deleted: boolean;
|
|
63
|
+
}>;
|
|
64
|
+
/** One item per key, in the order asked; absent keys have version 0. */
|
|
65
|
+
batchGet(owner: BlobOwnerKey, keys: string[]): Promise<BlobItem[]>;
|
|
66
|
+
/** All or nothing: one stale write fails the lot with VersionConflict. */
|
|
67
|
+
batchPut(owner: BlobOwnerKey, writes: BlobWrite[]): Promise<BlobInfo[]>;
|
|
68
|
+
list(owner: BlobOwnerKey): Promise<{
|
|
69
|
+
items: BlobInfo[];
|
|
70
|
+
totalBytes: number;
|
|
71
|
+
quotaBytes: number;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
74
|
+
export declare function createBlobClient(options: BlobClientOptions): BlobClient;
|
|
75
|
+
/** Read `key`, apply `change` to its value (undefined when absent), and
|
|
76
|
+
* write the result conditional on the version read -- re-reading and
|
|
77
|
+
* re-applying on a VersionConflict, up to `maxAttempts` times. `change`
|
|
78
|
+
* must therefore be a pure merge of "what's stored now" and "what I want",
|
|
79
|
+
* never a blind overwrite: that is what makes concurrent writers to one
|
|
80
|
+
* shared document safe. Returning undefined leaves the blob as it is. */
|
|
81
|
+
export declare function casUpdate<T>(client: BlobClient, owner: BlobOwnerKey, key: string, change: (current: T | undefined) => T | undefined, maxAttempts?: number): Promise<{
|
|
82
|
+
value: T | undefined;
|
|
83
|
+
version: number;
|
|
84
|
+
}>;
|
|
@@ -8,3 +8,5 @@ export type { RegistrationOptions, RegistrationLoop } from "./registration";
|
|
|
8
8
|
export { runConformance, assertConformance } from "./conformance";
|
|
9
9
|
export type { ConformanceOptions, ConformanceReport } from "./conformance";
|
|
10
10
|
export { PLUGIN_PROTOCOL_VERSION, runtimeVersion } from "./version";
|
|
11
|
+
export { createBlobClient, casUpdate, blobOwner, BlobStoreError, isVersionConflict } from "./blobClient";
|
|
12
|
+
export type { BlobClient, BlobClientOptions, BlobOwnerKey, Blob, BlobItem, BlobInfo, BlobWrite, BlobErrorType, } from "./blobClient";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anweather/game-plugin-ssdk",
|
|
3
3
|
"description": "Generated GamePlugin RPC types/server (plugin-protocol/model/game-plugin.smithy) plus a hand-written Express bridge and default-handler wrapper (./runtime) -- see plugin-protocol/CLAUDE.md's \"Publishing for cross-repo plugins\".",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.10.1",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "concurrently 'npm:build:cjs' 'npm:build:es' 'npm:build:types'",
|
|
7
7
|
"build:cjs": "tsc -p tsconfig.cjs.json",
|