@voltro/plugin-saves 0.0.0-stage → 0.88.0
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/CHANGELOG.md +24492 -0
- package/LICENSE +61 -0
- package/README.md +90 -2
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +5603 -0
- package/dist/contract.js +78 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.js +24 -0
- package/dist/index.d.ts +166 -0
- package/dist/index.js +5 -0
- package/dist/inspect.d.ts +82 -0
- package/dist/inspect.js +48 -0
- package/dist/plugin.js +335 -0
- package/dist/port.d.ts +103 -0
- package/dist/port.js +33 -0
- package/dist/rpc.d.ts +128 -0
- package/dist/rpc.js +85 -0
- package/dist/server.d.ts +286 -0
- package/dist/server.js +7 -0
- package/dist/service.server.js +412 -0
- package/dist/strategies.d.ts +76 -0
- package/dist/strategies.js +47 -0
- package/dist/tables.entity.js +60 -0
- package/dist/testing.d.ts +213 -0
- package/dist/testing.js +116 -0
- package/dist/web.d.ts +116 -0
- package/dist/web.js +4 -0
- package/package.json +88 -4
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { ConnectionRef } from '@voltro/kv/connection';
|
|
2
|
+
import { Context } from 'effect';
|
|
3
|
+
import { DataStore } from '@voltro/database';
|
|
4
|
+
import { Effect } from 'effect';
|
|
5
|
+
import { HotStoreShape } from '@voltro/kv/hot';
|
|
6
|
+
import { Layer } from 'effect';
|
|
7
|
+
import { PluginLifecycleContext } from '@voltro/protocol';
|
|
8
|
+
import { PluginPrivacyTarget } from '@voltro/protocol';
|
|
9
|
+
import { Schema } from 'effect';
|
|
10
|
+
import { Subject } from '@voltro/protocol';
|
|
11
|
+
import { VoltroPlugin } from '@voltro/protocol';
|
|
12
|
+
import { YieldableError } from 'effect/Cause';
|
|
13
|
+
|
|
14
|
+
declare class SaveConflict extends SaveConflict_base {
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
declare const SaveConflict_base: Schema.Class<SaveConflict, Schema.TaggedStruct<"SaveConflict", {
|
|
18
|
+
readonly serverVersion: Schema.Number;
|
|
19
|
+
readonly server: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Number, Schema.Boolean, Schema.Null]>>;
|
|
20
|
+
readonly client: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Number, Schema.Boolean, Schema.Null]>>;
|
|
21
|
+
}>, YieldableError>;
|
|
22
|
+
|
|
23
|
+
declare interface SaveDeleteIntent {
|
|
24
|
+
readonly slot: string;
|
|
25
|
+
readonly requestId: string;
|
|
26
|
+
readonly baseVersion: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare type SaveDocument = typeof SaveDocumentSchema.Type;
|
|
30
|
+
|
|
31
|
+
declare const SaveDocumentSchema: Schema.Struct<{
|
|
32
|
+
readonly bytes: Schema.Uint8ArrayFromBase64;
|
|
33
|
+
readonly slot: Schema.String;
|
|
34
|
+
readonly version: Schema.Number;
|
|
35
|
+
readonly schemaVersion: Schema.Number;
|
|
36
|
+
readonly byteLength: Schema.Number;
|
|
37
|
+
readonly checksum: Schema.String;
|
|
38
|
+
readonly deviceId: Schema.String;
|
|
39
|
+
readonly clientVersion: Schema.String;
|
|
40
|
+
readonly savedAt: Schema.Number;
|
|
41
|
+
readonly summary: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Number, Schema.Boolean, Schema.Null]>>;
|
|
42
|
+
readonly deletedUntil: Schema.NullOr<Schema.Number>;
|
|
43
|
+
}>;
|
|
44
|
+
|
|
45
|
+
declare type SaveError = SavesError | SaveConflict;
|
|
46
|
+
|
|
47
|
+
declare type SaveHeader = typeof SaveHeaderSchema.Type;
|
|
48
|
+
|
|
49
|
+
declare const SaveHeaderSchema: Schema.Struct<{
|
|
50
|
+
readonly slot: Schema.String;
|
|
51
|
+
readonly version: Schema.Number;
|
|
52
|
+
readonly schemaVersion: Schema.Number;
|
|
53
|
+
readonly byteLength: Schema.Number;
|
|
54
|
+
readonly checksum: Schema.String;
|
|
55
|
+
readonly deviceId: Schema.String;
|
|
56
|
+
readonly clientVersion: Schema.String;
|
|
57
|
+
readonly savedAt: Schema.Number;
|
|
58
|
+
readonly summary: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Number, Schema.Boolean, Schema.Null]>>;
|
|
59
|
+
readonly deletedUntil: Schema.NullOr<Schema.Number>;
|
|
60
|
+
}>;
|
|
61
|
+
|
|
62
|
+
export declare const savePutFixture: (patch?: Partial<SavePutIntent>) => SavePutIntent;
|
|
63
|
+
|
|
64
|
+
declare interface SavePutIntent {
|
|
65
|
+
readonly slot: string;
|
|
66
|
+
readonly requestId: string;
|
|
67
|
+
readonly baseVersion: number;
|
|
68
|
+
readonly schemaVersion: number;
|
|
69
|
+
readonly bytes: Uint8Array;
|
|
70
|
+
readonly deviceId: string;
|
|
71
|
+
readonly clientVersion: string;
|
|
72
|
+
readonly summary: SaveSummary;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
declare interface SaveRollbackIntent {
|
|
76
|
+
readonly slot: string;
|
|
77
|
+
readonly requestId: string;
|
|
78
|
+
readonly baseVersion: number;
|
|
79
|
+
readonly version: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare class SavesError extends SavesError_base {
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
declare const SavesError_base: Schema.Class<SavesError, Schema.TaggedStruct<"SavesError", {
|
|
86
|
+
readonly code: Schema.Literals<readonly ["invalid_input", "invalid_record", "forbidden", "not_found", "erased", "limit_exceeded", "invalid_save", "rate_limited", "unavailable", "request_conflict"]>;
|
|
87
|
+
}>, YieldableError>;
|
|
88
|
+
|
|
89
|
+
export declare const savesFakeLayer: Layer.Layer<SavesPort, SavesError, never>;
|
|
90
|
+
|
|
91
|
+
/** Registered actual DataStore adapter + actual HotStore memory admission. No native SQL or transport claim. */
|
|
92
|
+
export declare const savesFixture: (store: DataStore, patch?: Partial<SavesPluginOptions>) => Promise<{
|
|
93
|
+
store: DataStore;
|
|
94
|
+
plugin: SavesPlugin;
|
|
95
|
+
service: SavesService;
|
|
96
|
+
hotStore: HotStoreShape;
|
|
97
|
+
now: () => number;
|
|
98
|
+
setTime: (value: number) => void;
|
|
99
|
+
user: (id?: string, tenantId?: string) => {
|
|
100
|
+
type: "user";
|
|
101
|
+
kind: "guest";
|
|
102
|
+
id: string;
|
|
103
|
+
tenantId: string;
|
|
104
|
+
};
|
|
105
|
+
close: Effect.Effect<void, never, never>;
|
|
106
|
+
}>;
|
|
107
|
+
|
|
108
|
+
export declare const savesFixtureLifecycle: PluginLifecycleContext;
|
|
109
|
+
|
|
110
|
+
declare interface SavesOptions {
|
|
111
|
+
/** Server configuration, never a game/owner selector from the player. */
|
|
112
|
+
readonly gameId: string;
|
|
113
|
+
readonly slots?: readonly string[];
|
|
114
|
+
readonly maxBytes?: number;
|
|
115
|
+
readonly historyVersions?: number;
|
|
116
|
+
readonly maxRequests?: number;
|
|
117
|
+
readonly deleteGraceMs?: number;
|
|
118
|
+
readonly version?: string;
|
|
119
|
+
readonly validator?: SaveValidator;
|
|
120
|
+
readonly schema?: Schema.Top | undefined;
|
|
121
|
+
readonly schemaVersion?: number | undefined;
|
|
122
|
+
readonly now?: (() => number) | undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
declare interface SavesPlugin extends VoltroPlugin {
|
|
126
|
+
readonly saves: () => SavesService;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
declare interface SavesPluginOptions extends SavesOptions {
|
|
130
|
+
readonly service?: SavesService;
|
|
131
|
+
/** Actual app-owned invalidation sources required by a complete replacement. */
|
|
132
|
+
readonly querySources?: readonly string[];
|
|
133
|
+
readonly connection?: ConnectionRef<'redis'>;
|
|
134
|
+
/** Private fixture or single-node app-owned HotStore; never disposed here. */
|
|
135
|
+
readonly hotStore?: HotStoreShape;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
declare class SavesPort extends SavesPort_base {
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
declare const SavesPort_base: Context.ServiceClass<SavesPort, "@voltro/SavesPort", SavesService>;
|
|
142
|
+
|
|
143
|
+
export declare const savesPortFixture: Effect.Effect<{
|
|
144
|
+
store: DataStore;
|
|
145
|
+
plugin: SavesPlugin;
|
|
146
|
+
service: SavesService;
|
|
147
|
+
hotStore: HotStoreShape;
|
|
148
|
+
now: () => number;
|
|
149
|
+
setTime: (value: number) => void;
|
|
150
|
+
user: (id?: string, tenantId?: string) => {
|
|
151
|
+
type: "user";
|
|
152
|
+
kind: "guest";
|
|
153
|
+
id: string;
|
|
154
|
+
tenantId: string;
|
|
155
|
+
};
|
|
156
|
+
close: Effect.Effect<void, never, never>;
|
|
157
|
+
}, SavesError, never>;
|
|
158
|
+
|
|
159
|
+
export declare const savesPortSystemFixture: Readonly<{
|
|
160
|
+
kind: "port";
|
|
161
|
+
tag: typeof SavesPort;
|
|
162
|
+
fakeLayer: Layer.Layer<SavesPort, SavesError, never>;
|
|
163
|
+
probe: {
|
|
164
|
+
run: () => Effect.Effect<{
|
|
165
|
+
original: boolean;
|
|
166
|
+
bytes: number[] | null;
|
|
167
|
+
erased: boolean;
|
|
168
|
+
}, SaveError, never>;
|
|
169
|
+
expected: {
|
|
170
|
+
original: boolean;
|
|
171
|
+
bytes: number[];
|
|
172
|
+
erased: boolean;
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
}>;
|
|
176
|
+
|
|
177
|
+
declare interface SavesService {
|
|
178
|
+
readonly get: (subject: Subject, slot: string) => Effect.Effect<SaveDocument | null, SaveError>;
|
|
179
|
+
readonly list: (subject: Subject) => Effect.Effect<readonly SaveHeader[], SaveError>;
|
|
180
|
+
readonly history: (subject: Subject, slot: string) => Effect.Effect<readonly SaveHeader[], SaveError>;
|
|
181
|
+
readonly put: (subject: Subject, intent: SavePutIntent) => Effect.Effect<SaveHeader, SaveError>;
|
|
182
|
+
readonly rollback: (subject: Subject, intent: SaveRollbackIntent) => Effect.Effect<SaveHeader, SaveError>;
|
|
183
|
+
readonly remove: (subject: Subject, intent: SaveDeleteIntent) => Effect.Effect<SaveHeader, SaveError>;
|
|
184
|
+
readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, SaveError>;
|
|
185
|
+
readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, SaveError>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
declare type SaveSummary = typeof SaveSummarySchema.Type;
|
|
189
|
+
|
|
190
|
+
declare const SaveSummarySchema: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.String, Schema.Number, Schema.Boolean, Schema.Null]>>;
|
|
191
|
+
|
|
192
|
+
declare interface SaveValidationContext {
|
|
193
|
+
readonly previous: SaveDocument | null;
|
|
194
|
+
readonly proposed: SavePutIntent;
|
|
195
|
+
readonly decoded: unknown;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare type SaveValidator = (context: SaveValidationContext) => boolean;
|
|
199
|
+
|
|
200
|
+
export declare const saveValidatorSystemFixture: Readonly<{
|
|
201
|
+
kind: "slot";
|
|
202
|
+
defaultImplementation: SaveValidator;
|
|
203
|
+
defaultProbe: {
|
|
204
|
+
run: () => Effect.Effect<boolean, never, never>;
|
|
205
|
+
expected: boolean;
|
|
206
|
+
};
|
|
207
|
+
overrideProbe: {
|
|
208
|
+
run: () => Effect.Effect<boolean | "unavailable" | "invalid_input" | "invalid_record" | "forbidden" | "not_found" | "erased" | "limit_exceeded" | "invalid_save" | "rate_limited" | "request_conflict", never, never>;
|
|
209
|
+
expected: string;
|
|
210
|
+
};
|
|
211
|
+
}>;
|
|
212
|
+
|
|
213
|
+
export { }
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { savesError as e } from "./errors.js";
|
|
2
|
+
import { SavesPort as t } from "./port.js";
|
|
3
|
+
import { defaultSaveValidator as n, resolveSaveValidation as r } from "./strategies.js";
|
|
4
|
+
import { savesTables as i } from "./tables.entity.js";
|
|
5
|
+
import { savesPlugin as a } from "./plugin.js";
|
|
6
|
+
import { makeMemoryHotStore as o } from "@voltro/kv/hot";
|
|
7
|
+
import { Effect as s, Layer as c, Result as l } from "effect";
|
|
8
|
+
import { ensureTableRegistered as u } from "@voltro/database";
|
|
9
|
+
import { InMemoryDataStore as d } from "@voltro/runtime";
|
|
10
|
+
// src/testing.ts
|
|
11
|
+
var f = {
|
|
12
|
+
app: {
|
|
13
|
+
name: "saves-fixture",
|
|
14
|
+
type: "api",
|
|
15
|
+
voltroVersion: "0.83.1"
|
|
16
|
+
},
|
|
17
|
+
env: { NODE_ENV: "test" },
|
|
18
|
+
config: {},
|
|
19
|
+
logger: {
|
|
20
|
+
info() {},
|
|
21
|
+
warn() {},
|
|
22
|
+
error() {},
|
|
23
|
+
debug() {}
|
|
24
|
+
}
|
|
25
|
+
}, p = (e = {}) => ({
|
|
26
|
+
slot: "main",
|
|
27
|
+
requestId: "fixture.put",
|
|
28
|
+
baseVersion: 0,
|
|
29
|
+
schemaVersion: 1,
|
|
30
|
+
bytes: Uint8Array.of(0, 1, 255),
|
|
31
|
+
deviceId: "fixture.device",
|
|
32
|
+
clientVersion: "fixture.client.1",
|
|
33
|
+
summary: { chapter: 1 },
|
|
34
|
+
...e
|
|
35
|
+
}), m = async (e, t = {}) => {
|
|
36
|
+
i.forEach(u);
|
|
37
|
+
let n = 1e3, r = await s.runPromise(o()), c = a({
|
|
38
|
+
gameId: "fixture.game",
|
|
39
|
+
slots: ["main", "profile-2"],
|
|
40
|
+
now: () => n,
|
|
41
|
+
hotStore: r,
|
|
42
|
+
...t
|
|
43
|
+
});
|
|
44
|
+
return await c.bindDataStore?.(e), await s.runPromise(c.onActivate(f)), {
|
|
45
|
+
store: e,
|
|
46
|
+
plugin: c,
|
|
47
|
+
service: c.saves(),
|
|
48
|
+
hotStore: r,
|
|
49
|
+
now: () => n,
|
|
50
|
+
setTime: (e) => {
|
|
51
|
+
n = e;
|
|
52
|
+
},
|
|
53
|
+
user: (e = "fixture.owner", t = "fixture.tenant") => ({
|
|
54
|
+
type: "user",
|
|
55
|
+
kind: "guest",
|
|
56
|
+
id: e,
|
|
57
|
+
tenantId: t
|
|
58
|
+
}),
|
|
59
|
+
close: s.suspend(() => c.onDeactivate(f)).pipe(s.orDie)
|
|
60
|
+
};
|
|
61
|
+
}, h = s.tryPromise({
|
|
62
|
+
try: () => m(new d()),
|
|
63
|
+
catch: () => e("unavailable")
|
|
64
|
+
}), g = c.effect(t, s.acquireRelease(h, (e) => e.close).pipe(s.map((e) => e.service))), _ = Object.freeze({
|
|
65
|
+
kind: "port",
|
|
66
|
+
tag: t,
|
|
67
|
+
fakeLayer: g,
|
|
68
|
+
probe: {
|
|
69
|
+
run: () => s.scoped(s.gen(function* () {
|
|
70
|
+
let e = yield* t, n = {
|
|
71
|
+
type: "user",
|
|
72
|
+
id: "fixture.owner",
|
|
73
|
+
tenantId: "fixture.tenant"
|
|
74
|
+
}, r = p(), i = yield* e.put(n, r), a = yield* e.put(n, r), o = yield* e.get(n, r.slot);
|
|
75
|
+
yield* e.eraseSubject({
|
|
76
|
+
subjectId: n.id,
|
|
77
|
+
tenantId: n.tenantId,
|
|
78
|
+
kind: "guest"
|
|
79
|
+
});
|
|
80
|
+
let c = yield* e.get(n, r.slot).pipe(s.result);
|
|
81
|
+
return {
|
|
82
|
+
original: i.version === a.version,
|
|
83
|
+
bytes: o ? Array.from(o.bytes) : null,
|
|
84
|
+
erased: l.isFailure(c) && c.failure._tag === "SavesError" && c.failure.code === "erased"
|
|
85
|
+
};
|
|
86
|
+
}).pipe(s.provide(g))),
|
|
87
|
+
expected: {
|
|
88
|
+
original: !0,
|
|
89
|
+
bytes: [
|
|
90
|
+
0,
|
|
91
|
+
1,
|
|
92
|
+
255
|
|
93
|
+
],
|
|
94
|
+
erased: !0
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}), v = () => Object.freeze({
|
|
98
|
+
previous: null,
|
|
99
|
+
proposed: p(),
|
|
100
|
+
decoded: null
|
|
101
|
+
}), y = Object.freeze({
|
|
102
|
+
kind: "slot",
|
|
103
|
+
defaultImplementation: n,
|
|
104
|
+
defaultProbe: {
|
|
105
|
+
run: () => s.sync(() => (r(v()), !0)),
|
|
106
|
+
expected: !0
|
|
107
|
+
},
|
|
108
|
+
overrideProbe: {
|
|
109
|
+
run: () => s.try({
|
|
110
|
+
try: () => (r(v(), () => !1), !0),
|
|
111
|
+
catch: () => e("invalid_save")
|
|
112
|
+
}).pipe(s.catch((e) => s.succeed(e.code))),
|
|
113
|
+
expected: "invalid_save"
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
export { p as savePutFixture, y as saveValidatorSystemFixture, g as savesFakeLayer, m as savesFixture, f as savesFixtureLifecycle, h as savesPortFixture, _ as savesPortSystemFixture };
|
package/dist/web.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ActionState } from '@voltro/client';
|
|
2
|
+
import { SubscriptionIdle } from '@voltro/client';
|
|
3
|
+
import { SubscriptionState } from '@voltro/client';
|
|
4
|
+
|
|
5
|
+
export declare const usePutSave: (apiName?: string) => ActionState<{
|
|
6
|
+
readonly schemaVersion: number;
|
|
7
|
+
readonly bytes: Uint8Array<ArrayBufferLike>;
|
|
8
|
+
readonly deviceId: string;
|
|
9
|
+
readonly clientVersion: string;
|
|
10
|
+
readonly summary: {
|
|
11
|
+
readonly [x: string]: string | number | boolean | null;
|
|
12
|
+
};
|
|
13
|
+
readonly slot: string;
|
|
14
|
+
readonly requestId: string;
|
|
15
|
+
readonly baseVersion: number;
|
|
16
|
+
}, {
|
|
17
|
+
readonly slot: string;
|
|
18
|
+
readonly version: number;
|
|
19
|
+
readonly schemaVersion: number;
|
|
20
|
+
readonly byteLength: number;
|
|
21
|
+
readonly checksum: string;
|
|
22
|
+
readonly deviceId: string;
|
|
23
|
+
readonly clientVersion: string;
|
|
24
|
+
readonly savedAt: number;
|
|
25
|
+
readonly summary: {
|
|
26
|
+
readonly [x: string]: string | number | boolean | null;
|
|
27
|
+
};
|
|
28
|
+
readonly deletedUntil: number | null;
|
|
29
|
+
}>;
|
|
30
|
+
|
|
31
|
+
export declare const useRemoveSave: (apiName?: string) => ActionState<{
|
|
32
|
+
readonly slot: string;
|
|
33
|
+
readonly requestId: string;
|
|
34
|
+
readonly baseVersion: number;
|
|
35
|
+
}, {
|
|
36
|
+
readonly slot: string;
|
|
37
|
+
readonly version: number;
|
|
38
|
+
readonly schemaVersion: number;
|
|
39
|
+
readonly byteLength: number;
|
|
40
|
+
readonly checksum: string;
|
|
41
|
+
readonly deviceId: string;
|
|
42
|
+
readonly clientVersion: string;
|
|
43
|
+
readonly savedAt: number;
|
|
44
|
+
readonly summary: {
|
|
45
|
+
readonly [x: string]: string | number | boolean | null;
|
|
46
|
+
};
|
|
47
|
+
readonly deletedUntil: number | null;
|
|
48
|
+
}>;
|
|
49
|
+
|
|
50
|
+
export declare const useRollbackSave: (apiName?: string) => ActionState<{
|
|
51
|
+
readonly version: number;
|
|
52
|
+
readonly slot: string;
|
|
53
|
+
readonly requestId: string;
|
|
54
|
+
readonly baseVersion: number;
|
|
55
|
+
}, {
|
|
56
|
+
readonly slot: string;
|
|
57
|
+
readonly version: number;
|
|
58
|
+
readonly schemaVersion: number;
|
|
59
|
+
readonly byteLength: number;
|
|
60
|
+
readonly checksum: string;
|
|
61
|
+
readonly deviceId: string;
|
|
62
|
+
readonly clientVersion: string;
|
|
63
|
+
readonly savedAt: number;
|
|
64
|
+
readonly summary: {
|
|
65
|
+
readonly [x: string]: string | number | boolean | null;
|
|
66
|
+
};
|
|
67
|
+
readonly deletedUntil: number | null;
|
|
68
|
+
}>;
|
|
69
|
+
|
|
70
|
+
export declare const useSave: (slot: string | undefined, apiName?: string) => SubscriptionIdle | SubscriptionState<{
|
|
71
|
+
readonly bytes: Uint8Array<ArrayBufferLike>;
|
|
72
|
+
readonly slot: string;
|
|
73
|
+
readonly version: number;
|
|
74
|
+
readonly schemaVersion: number;
|
|
75
|
+
readonly byteLength: number;
|
|
76
|
+
readonly checksum: string;
|
|
77
|
+
readonly deviceId: string;
|
|
78
|
+
readonly clientVersion: string;
|
|
79
|
+
readonly savedAt: number;
|
|
80
|
+
readonly summary: {
|
|
81
|
+
readonly [x: string]: string | number | boolean | null;
|
|
82
|
+
};
|
|
83
|
+
readonly deletedUntil: number | null;
|
|
84
|
+
} | null>;
|
|
85
|
+
|
|
86
|
+
export declare const useSaveHistory: (slot: string | undefined, apiName?: string) => SubscriptionIdle | SubscriptionState<readonly {
|
|
87
|
+
readonly slot: string;
|
|
88
|
+
readonly version: number;
|
|
89
|
+
readonly schemaVersion: number;
|
|
90
|
+
readonly byteLength: number;
|
|
91
|
+
readonly checksum: string;
|
|
92
|
+
readonly deviceId: string;
|
|
93
|
+
readonly clientVersion: string;
|
|
94
|
+
readonly savedAt: number;
|
|
95
|
+
readonly summary: {
|
|
96
|
+
readonly [x: string]: string | number | boolean | null;
|
|
97
|
+
};
|
|
98
|
+
readonly deletedUntil: number | null;
|
|
99
|
+
}[]>;
|
|
100
|
+
|
|
101
|
+
export declare const useSaveSlots: (apiName?: string) => SubscriptionState<readonly {
|
|
102
|
+
readonly slot: string;
|
|
103
|
+
readonly version: number;
|
|
104
|
+
readonly schemaVersion: number;
|
|
105
|
+
readonly byteLength: number;
|
|
106
|
+
readonly checksum: string;
|
|
107
|
+
readonly deviceId: string;
|
|
108
|
+
readonly clientVersion: string;
|
|
109
|
+
readonly savedAt: number;
|
|
110
|
+
readonly summary: {
|
|
111
|
+
readonly [x: string]: string | number | boolean | null;
|
|
112
|
+
};
|
|
113
|
+
readonly deletedUntil: number | null;
|
|
114
|
+
}[]>;
|
|
115
|
+
|
|
116
|
+
export { }
|
package/dist/web.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { useAction as e, useSubscription as t } from "@voltro/client";
|
|
2
|
+
// src/web.ts
|
|
3
|
+
var n = (e, n = "app") => t(n, "saves.get", { slot: e ?? "" }, { skip: e === void 0 }), r = (e = "app") => t(e, "saves.list", {}), i = (e, n = "app") => t(n, "saves.history", { slot: e ?? "" }, { skip: e === void 0 }), a = (t = "app") => e(t, "saves.put"), o = (t = "app") => e(t, "saves.rollback"), s = (t = "app") => e(t, "saves.remove");
|
|
4
|
+
export { a as usePutSave, s as useRemoveSave, o as useRollbackSave, n as useSave, i as useSaveHistory, r as useSaveSlots };
|
package/package.json
CHANGED
|
@@ -1,6 +1,90 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/plugin-saves",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.88.0",
|
|
4
|
+
"description": "Owner-scoped opaque saves with SQL versions, original-intent receipts, history and privacy.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"voltro",
|
|
7
|
+
"typescript",
|
|
8
|
+
"framework"
|
|
9
|
+
],
|
|
10
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
11
|
+
"homepage": "https://voltro.dev",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"email": "support@voltro.dev"
|
|
14
|
+
},
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "Voltro UG",
|
|
17
|
+
"url": "https://voltro.dev"
|
|
18
|
+
},
|
|
19
|
+
"type": "module",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./server": {
|
|
27
|
+
"types": "./dist/server.d.ts",
|
|
28
|
+
"import": "./dist/server.js",
|
|
29
|
+
"default": "./dist/server.js"
|
|
30
|
+
},
|
|
31
|
+
"./errors": {
|
|
32
|
+
"types": "./dist/errors.d.ts",
|
|
33
|
+
"import": "./dist/errors.js",
|
|
34
|
+
"default": "./dist/errors.js"
|
|
35
|
+
},
|
|
36
|
+
"./rpc": {
|
|
37
|
+
"types": "./dist/rpc.d.ts",
|
|
38
|
+
"import": "./dist/rpc.js",
|
|
39
|
+
"default": "./dist/rpc.js"
|
|
40
|
+
},
|
|
41
|
+
"./port": {
|
|
42
|
+
"types": "./dist/port.d.ts",
|
|
43
|
+
"import": "./dist/port.js",
|
|
44
|
+
"default": "./dist/port.js"
|
|
45
|
+
},
|
|
46
|
+
"./strategies": {
|
|
47
|
+
"types": "./dist/strategies.d.ts",
|
|
48
|
+
"import": "./dist/strategies.js",
|
|
49
|
+
"default": "./dist/strategies.js"
|
|
50
|
+
},
|
|
51
|
+
"./testing": {
|
|
52
|
+
"types": "./dist/testing.d.ts",
|
|
53
|
+
"import": "./dist/testing.js",
|
|
54
|
+
"default": "./dist/testing.js"
|
|
55
|
+
},
|
|
56
|
+
"./web": {
|
|
57
|
+
"types": "./dist/web.d.ts",
|
|
58
|
+
"import": "./dist/web.js",
|
|
59
|
+
"default": "./dist/web.js"
|
|
60
|
+
},
|
|
61
|
+
"./package.json": "./package.json",
|
|
62
|
+
"./inspect": {
|
|
63
|
+
"types": "./dist/inspect.d.ts",
|
|
64
|
+
"import": "./dist/inspect.js",
|
|
65
|
+
"default": "./dist/inspect.js"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"main": "./dist/index.js",
|
|
69
|
+
"module": "./dist/index.js",
|
|
70
|
+
"types": "./dist/index.d.ts",
|
|
71
|
+
"sideEffects": false,
|
|
72
|
+
"engines": {
|
|
73
|
+
"node": ">=24.0.0"
|
|
74
|
+
},
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"@voltro/protocol": "0.88.0",
|
|
77
|
+
"@voltro/database": "0.88.0",
|
|
78
|
+
"@voltro/kv": "0.88.0",
|
|
79
|
+
"@voltro/client": "0.88.0",
|
|
80
|
+
"@voltro/runtime": "0.88.0",
|
|
81
|
+
"@voltro/plugin-licensing": "0.88.0"
|
|
82
|
+
},
|
|
83
|
+
"peerDependencies": {
|
|
84
|
+
"effect": "4.1.0",
|
|
85
|
+
"react": "^19.0.0"
|
|
86
|
+
},
|
|
87
|
+
"publishConfig": {
|
|
88
|
+
"access": "public"
|
|
89
|
+
}
|
|
90
|
+
}
|