@voltro/plugin-inventory 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.
@@ -0,0 +1,816 @@
1
+ import { ColumnBuilder } from '@voltro/database';
2
+ import { DataStore } from '@voltro/database';
3
+ import { Effect } from 'effect';
4
+ import { FieldDefinitions } from '@voltro/database';
5
+ import { PluginPrivacyTarget } from '@voltro/protocol';
6
+ import { PreparedSqlMutation } from '@voltro/database/sql';
7
+ import { Schema } from 'effect';
8
+ import { Subject } from '@voltro/protocol';
9
+ import { Table } from '@voltro/database';
10
+ import { YieldableError } from 'effect/Cause';
11
+
12
+ export declare interface CatalogImport extends CatalogScope {
13
+ readonly revision: string;
14
+ readonly items: readonly CatalogItem[];
15
+ }
16
+
17
+ /** Serializable content uses a declared item's version, never a stored Schema object. */
18
+ declare interface CatalogItem {
19
+ readonly id: string;
20
+ readonly schemaVersion: number;
21
+ readonly kind: ItemKind;
22
+ readonly stackable: boolean;
23
+ readonly maxStack: number;
24
+ readonly tradable: boolean;
25
+ readonly rarity: string;
26
+ readonly tags: readonly string[];
27
+ readonly equipSlot: string | null;
28
+ readonly expiresAfter: number | null;
29
+ readonly display: {
30
+ readonly nameKey: string;
31
+ readonly icon: string | null;
32
+ };
33
+ readonly attributes: JsonValue;
34
+ readonly instanceDefaults: JsonValue;
35
+ }
36
+
37
+ declare interface CatalogScope {
38
+ readonly tenantId: string;
39
+ readonly channel: string;
40
+ readonly locale: string;
41
+ }
42
+
43
+ declare interface CatalogSnapshot {
44
+ readonly revision: string;
45
+ readonly items: readonly CatalogItem[];
46
+ }
47
+
48
+ /** Read only. Call at join/workflow boundaries, never from a room tick. */
49
+ declare interface CatalogSourceService {
50
+ readonly read: (scope: CatalogScope) => Effect.Effect<CatalogSnapshot, InventoryError>;
51
+ }
52
+
53
+ declare interface CraftEconomyParticipant {
54
+ readonly prepareTransfer: (subject: Subject, input: {
55
+ readonly tenantId: string;
56
+ readonly requestId: string;
57
+ readonly currency: string;
58
+ readonly amount: string;
59
+ readonly from: {
60
+ readonly kind: 'wallet';
61
+ readonly ownerKind: 'player' | 'guild';
62
+ readonly ownerId: string;
63
+ };
64
+ readonly to: {
65
+ readonly kind: 'system';
66
+ readonly id: string;
67
+ };
68
+ readonly reason: string;
69
+ readonly ref: {
70
+ readonly kind: string;
71
+ readonly id: string;
72
+ };
73
+ }) => Effect.Effect<PreparedSqlMutation<CraftPaymentReceipt>, {
74
+ readonly code: string;
75
+ }>;
76
+ }
77
+
78
+ declare interface CraftingOptions {
79
+ readonly recipes: readonly (RecipeDefinition | Recipe)[];
80
+ readonly craftResolver?: CraftResolver | undefined;
81
+ readonly version?: string | undefined;
82
+ readonly service?: CraftingService | undefined;
83
+ readonly economy?: CraftEconomyParticipant | undefined;
84
+ readonly systemAccount?: string | undefined;
85
+ }
86
+
87
+ /** Small independent seam; InventoryPort retains its eight-method surface. */
88
+ declare interface CraftingService {
89
+ readonly craft: (subject: Subject, input: CraftRequest) => Effect.Effect<InventoryReceipt, InventoryError>;
90
+ readonly recipes: (subject: Subject) => Effect.Effect<readonly Recipe[], InventoryError>;
91
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, InventoryError>;
92
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, InventoryError>;
93
+ }
94
+
95
+ declare interface CraftInput {
96
+ readonly recipe: Recipe;
97
+ readonly batches: number;
98
+ readonly at: number;
99
+ readonly available: readonly InventoryInstance[];
100
+ readonly excludedIds: readonly string[];
101
+ }
102
+
103
+ declare interface CraftPaymentReceipt {
104
+ readonly txId: string;
105
+ readonly currency: string;
106
+ readonly amount: string;
107
+ readonly at: number;
108
+ }
109
+
110
+ declare interface CraftPlan {
111
+ readonly consume: readonly {
112
+ readonly instanceId: string;
113
+ readonly qty: number;
114
+ }[];
115
+ readonly outputs: readonly RecipeOutput[];
116
+ }
117
+
118
+ declare interface CraftRequest {
119
+ readonly tenantId: string;
120
+ readonly owner: InventoryOwner;
121
+ readonly recipeId: string;
122
+ readonly requestId: string;
123
+ readonly batches?: number;
124
+ }
125
+
126
+ declare type CraftResolver = (input: CraftInput) => CraftPlan;
127
+
128
+ /** SQL source owns immutable snapshots and a tenant-wide identity/version registry. */
129
+ export declare const dataStoreCatalog: (store: DataStore, input: SqlCatalogOptions) => Readonly<{
130
+ read: (scope: CatalogScope) => Effect.Effect<CatalogSnapshot, InventoryError>;
131
+ importSnapshot: (subject: Subject, input: CatalogImport) => Effect.Effect<CatalogSnapshot, InventoryError>;
132
+ }>;
133
+
134
+ /** Borrow the app's SQL store. All mutations serialize on a durable owner fence. */
135
+ export declare const dataStoreInventory: (store: DataStore, input: InventoryStoreOptions) => InventorySqlService;
136
+
137
+ declare interface ExpiryInput {
138
+ readonly item: CatalogItem;
139
+ readonly acquiredAt: number;
140
+ }
141
+
142
+ declare type ExpiryPolicy = (input: ExpiryInput) => number | null;
143
+
144
+ export declare interface InventoryAudit {
145
+ readonly instances: number;
146
+ readonly ledgerRows: number;
147
+ readonly matches: boolean;
148
+ }
149
+
150
+ export declare const inventoryCatalogHeadsTable: Table<"_voltro_inv_catalog_heads", FieldDefinitions<{
151
+ readonly id: ColumnBuilder<string, "id", boolean>;
152
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
153
+ readonly channel: ColumnBuilder<string, "text", boolean>;
154
+ readonly locale: ColumnBuilder<string, "text", boolean>;
155
+ readonly revision: ColumnBuilder<string, "text", boolean>;
156
+ readonly updatedAt: ColumnBuilder<Date, "timestamp", boolean>;
157
+ }>, true, never>;
158
+
159
+ export declare const inventoryCatalogLocksTable: Table<"_voltro_inv_catalog_locks", FieldDefinitions<{
160
+ readonly id: ColumnBuilder<string, "id", boolean>;
161
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
162
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
163
+ }>, true, never>;
164
+
165
+ export declare const inventoryCatalogRevisionsTable: Table<"_voltro_inv_catalog_revisions", FieldDefinitions<{
166
+ readonly id: ColumnBuilder<string, "id", boolean>;
167
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
168
+ readonly revision: ColumnBuilder<string, "text", boolean>;
169
+ readonly channel: ColumnBuilder<string, "text", boolean>;
170
+ readonly locale: ColumnBuilder<string, "text", boolean>;
171
+ readonly digest: ColumnBuilder<string, "text", boolean>;
172
+ readonly itemCount: ColumnBuilder<number, "integer", boolean>;
173
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
174
+ }>, true, "voltro_inv_catalog_revisions_scope_idx">;
175
+
176
+ export declare const inventoryCatalogTable: Table<"_voltro_inv_catalog", FieldDefinitions<{
177
+ readonly id: ColumnBuilder<string, "id", boolean>;
178
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
179
+ readonly revision: ColumnBuilder<string, "text", boolean>;
180
+ readonly channel: ColumnBuilder<string, "text", boolean>;
181
+ readonly locale: ColumnBuilder<string, "text", boolean>;
182
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
183
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
184
+ }>, true, never>;
185
+
186
+ export declare const inventoryCatalogTables: readonly [ Table<"_voltro_inv_catalog_locks", FieldDefinitions<{
187
+ readonly id: ColumnBuilder<string, "id", boolean>;
188
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
189
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
190
+ }>, true, never>, Table<"_voltro_inv_catalog_heads", FieldDefinitions<{
191
+ readonly id: ColumnBuilder<string, "id", boolean>;
192
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
193
+ readonly channel: ColumnBuilder<string, "text", boolean>;
194
+ readonly locale: ColumnBuilder<string, "text", boolean>;
195
+ readonly revision: ColumnBuilder<string, "text", boolean>;
196
+ readonly updatedAt: ColumnBuilder<Date, "timestamp", boolean>;
197
+ }>, true, never>, Table<"_voltro_inv_catalog", FieldDefinitions<{
198
+ readonly id: ColumnBuilder<string, "id", boolean>;
199
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
200
+ readonly revision: ColumnBuilder<string, "text", boolean>;
201
+ readonly channel: ColumnBuilder<string, "text", boolean>;
202
+ readonly locale: ColumnBuilder<string, "text", boolean>;
203
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
204
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
205
+ }>, true, never>, Table<"_voltro_inv_catalog_versions", FieldDefinitions<{
206
+ readonly id: ColumnBuilder<string, "id", boolean>;
207
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
208
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
209
+ readonly schemaVersion: ColumnBuilder<number, "integer", boolean>;
210
+ readonly kind: ColumnBuilder<string, "text", boolean>;
211
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
212
+ }>, true, never>, Table<"_voltro_inv_catalog_revisions", FieldDefinitions<{
213
+ readonly id: ColumnBuilder<string, "id", boolean>;
214
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
215
+ readonly revision: ColumnBuilder<string, "text", boolean>;
216
+ readonly channel: ColumnBuilder<string, "text", boolean>;
217
+ readonly locale: ColumnBuilder<string, "text", boolean>;
218
+ readonly digest: ColumnBuilder<string, "text", boolean>;
219
+ readonly itemCount: ColumnBuilder<number, "integer", boolean>;
220
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
221
+ }>, true, "voltro_inv_catalog_revisions_scope_idx">];
222
+
223
+ export declare const inventoryCatalogVersionsTable: Table<"_voltro_inv_catalog_versions", FieldDefinitions<{
224
+ readonly id: ColumnBuilder<string, "id", boolean>;
225
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
226
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
227
+ readonly schemaVersion: ColumnBuilder<number, "integer", boolean>;
228
+ readonly kind: ColumnBuilder<string, "text", boolean>;
229
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
230
+ }>, true, never>;
231
+
232
+ declare interface InventoryConsume {
233
+ readonly tenantId: string;
234
+ readonly owner: InventoryOwner;
235
+ readonly requestId: string;
236
+ readonly instanceId: string;
237
+ readonly qty: number;
238
+ readonly reason: string;
239
+ readonly ref: InventoryRef;
240
+ }
241
+
242
+ declare interface InventoryEquip {
243
+ readonly slotSet: string;
244
+ readonly slot: string;
245
+ readonly instanceId: string | null;
246
+ readonly requestId: string;
247
+ }
248
+
249
+ /** Public errors carry codes, never subjects, catalog values or provider causes. */
250
+ declare class InventoryError extends InventoryError_base {
251
+ }
252
+
253
+ declare const InventoryError_base: Schema.Class<InventoryError, Schema.TaggedStruct<"InventoryError", {
254
+ readonly code: Schema.Literals<readonly ["invalid_input", "invalid_record", "invalid_item", "invalid_attributes", "conflict", "forbidden", "not_found", "unavailable", "limit_exceeded", "erased", "insufficient_items", "insufficient_funds", "payment_refused", "locked", "expired", "invalid_slot"]>;
255
+ }>, YieldableError>;
256
+
257
+ declare interface InventoryExpire {
258
+ readonly tenantId: string;
259
+ readonly owner: InventoryOwner;
260
+ readonly requestId: string;
261
+ readonly until: number;
262
+ }
263
+
264
+ declare interface InventoryGrant {
265
+ readonly tenantId: string;
266
+ readonly owner: InventoryOwner;
267
+ readonly requestId: string;
268
+ readonly itemId: string;
269
+ readonly qty: number;
270
+ readonly attributes?: JsonValue;
271
+ readonly reason: string;
272
+ readonly ref: InventoryRef;
273
+ }
274
+
275
+ declare interface InventoryInstance {
276
+ readonly id: string;
277
+ readonly itemId: string;
278
+ readonly schemaVersion: number;
279
+ readonly qty: number;
280
+ readonly attributes: JsonValue;
281
+ readonly acquiredAt: number;
282
+ readonly expiresAt: number | null;
283
+ readonly locked: boolean;
284
+ readonly source: string;
285
+ }
286
+
287
+ export declare const inventoryItemsTable: Table<"_voltro_inv_items", FieldDefinitions<{
288
+ readonly id: ColumnBuilder<string, "id", boolean>;
289
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
290
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
291
+ readonly ownerId: ColumnBuilder<string, "text", boolean>;
292
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
293
+ readonly schemaVersion: ColumnBuilder<number, "integer", boolean>;
294
+ readonly qty: ColumnBuilder<number, "integer", boolean>;
295
+ readonly attributes: ColumnBuilder<unknown, "json", boolean>;
296
+ readonly acquiredAt: ColumnBuilder<Date, "timestamp", boolean>;
297
+ readonly expiresAt: ColumnBuilder<Date | null, "timestamp", boolean>;
298
+ readonly locked: ColumnBuilder<boolean, "boolean", boolean>;
299
+ readonly source: ColumnBuilder<string, "text", boolean>;
300
+ }>, true, never>;
301
+
302
+ export declare const inventoryLedgerTable: Table<"_voltro_inv_ledger", FieldDefinitions<{
303
+ readonly id: ColumnBuilder<string, "id", boolean>;
304
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
305
+ readonly operationId: ColumnBuilder<string, "text", boolean>;
306
+ readonly ownerKind: ColumnBuilder<"player" | "guild" | null, "text", boolean>;
307
+ readonly sequence: ColumnBuilder<number, "integer", boolean>;
308
+ readonly ownerId: ColumnBuilder<string | null, "text", boolean>;
309
+ readonly instanceId: ColumnBuilder<string | null, "text", boolean>;
310
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
311
+ readonly delta: ColumnBuilder<number, "integer", boolean>;
312
+ readonly reason: ColumnBuilder<string, "text", boolean>;
313
+ readonly after: ColumnBuilder<unknown, "json", boolean>;
314
+ readonly refKind: ColumnBuilder<string | null, "text", boolean>;
315
+ readonly refId: ColumnBuilder<string | null, "text", boolean>;
316
+ readonly actor: ColumnBuilder<string | null, "text", boolean>;
317
+ readonly at: ColumnBuilder<Date, "timestamp", boolean>;
318
+ }>, true, never>;
319
+
320
+ declare interface InventoryLoadout {
321
+ readonly slotSet: string;
322
+ readonly slot: string;
323
+ readonly instanceId: string;
324
+ }
325
+
326
+ export declare const inventoryLoadoutsTable: Table<"_voltro_inv_loadouts", FieldDefinitions<{
327
+ readonly id: ColumnBuilder<string, "id", boolean>;
328
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
329
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
330
+ readonly ownerId: ColumnBuilder<string, "text", boolean>;
331
+ readonly slotSet: ColumnBuilder<string, "text", boolean>;
332
+ readonly slot: ColumnBuilder<string, "text", boolean>;
333
+ readonly instanceId: ColumnBuilder<string, "text", boolean>;
334
+ }>, true, never>;
335
+
336
+ export declare const inventoryOperationsTable: Table<"_voltro_inv_operations", FieldDefinitions<{
337
+ readonly id: ColumnBuilder<string, "id", boolean>;
338
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
339
+ readonly state: ColumnBuilder<"pending" | "erased" | "committed", "text", boolean>;
340
+ readonly ownerKey: ColumnBuilder<string | null, "text", boolean>;
341
+ readonly sequence: ColumnBuilder<number | null, "integer", boolean>;
342
+ readonly craft: ColumnBuilder<unknown, "json", boolean>;
343
+ readonly reservation: ColumnBuilder<unknown, "json", boolean>;
344
+ readonly transfer: ColumnBuilder<unknown, "json", boolean>;
345
+ readonly digest: ColumnBuilder<string | null, "text", boolean>;
346
+ readonly receipt: ColumnBuilder<unknown, "json", boolean>;
347
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
348
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
349
+ }>, true, never>;
350
+
351
+ export declare const inventoryOwnedTables: readonly [ Table<"_voltro_inv_subjects", FieldDefinitions<{
352
+ readonly id: ColumnBuilder<string, "id", boolean>;
353
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
354
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
355
+ readonly ownerId: ColumnBuilder<string | null, "text", boolean>;
356
+ readonly erased: ColumnBuilder<boolean, "boolean", boolean>;
357
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
358
+ readonly sequence: ColumnBuilder<number, "integer", boolean>;
359
+ }>, true, never>, Table<"_voltro_inv_items", FieldDefinitions<{
360
+ readonly id: ColumnBuilder<string, "id", boolean>;
361
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
362
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
363
+ readonly ownerId: ColumnBuilder<string, "text", boolean>;
364
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
365
+ readonly schemaVersion: ColumnBuilder<number, "integer", boolean>;
366
+ readonly qty: ColumnBuilder<number, "integer", boolean>;
367
+ readonly attributes: ColumnBuilder<unknown, "json", boolean>;
368
+ readonly acquiredAt: ColumnBuilder<Date, "timestamp", boolean>;
369
+ readonly expiresAt: ColumnBuilder<Date | null, "timestamp", boolean>;
370
+ readonly locked: ColumnBuilder<boolean, "boolean", boolean>;
371
+ readonly source: ColumnBuilder<string, "text", boolean>;
372
+ }>, true, never>, Table<"_voltro_inv_loadouts", FieldDefinitions<{
373
+ readonly id: ColumnBuilder<string, "id", boolean>;
374
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
375
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
376
+ readonly ownerId: ColumnBuilder<string, "text", boolean>;
377
+ readonly slotSet: ColumnBuilder<string, "text", boolean>;
378
+ readonly slot: ColumnBuilder<string, "text", boolean>;
379
+ readonly instanceId: ColumnBuilder<string, "text", boolean>;
380
+ }>, true, never>, Table<"_voltro_inv_ledger", FieldDefinitions<{
381
+ readonly id: ColumnBuilder<string, "id", boolean>;
382
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
383
+ readonly operationId: ColumnBuilder<string, "text", boolean>;
384
+ readonly ownerKind: ColumnBuilder<"player" | "guild" | null, "text", boolean>;
385
+ readonly sequence: ColumnBuilder<number, "integer", boolean>;
386
+ readonly ownerId: ColumnBuilder<string | null, "text", boolean>;
387
+ readonly instanceId: ColumnBuilder<string | null, "text", boolean>;
388
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
389
+ readonly delta: ColumnBuilder<number, "integer", boolean>;
390
+ readonly reason: ColumnBuilder<string, "text", boolean>;
391
+ readonly after: ColumnBuilder<unknown, "json", boolean>;
392
+ readonly refKind: ColumnBuilder<string | null, "text", boolean>;
393
+ readonly refId: ColumnBuilder<string | null, "text", boolean>;
394
+ readonly actor: ColumnBuilder<string | null, "text", boolean>;
395
+ readonly at: ColumnBuilder<Date, "timestamp", boolean>;
396
+ }>, true, never>, Table<"_voltro_inv_operations", FieldDefinitions<{
397
+ readonly id: ColumnBuilder<string, "id", boolean>;
398
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
399
+ readonly state: ColumnBuilder<"pending" | "erased" | "committed", "text", boolean>;
400
+ readonly ownerKey: ColumnBuilder<string | null, "text", boolean>;
401
+ readonly sequence: ColumnBuilder<number | null, "integer", boolean>;
402
+ readonly craft: ColumnBuilder<unknown, "json", boolean>;
403
+ readonly reservation: ColumnBuilder<unknown, "json", boolean>;
404
+ readonly transfer: ColumnBuilder<unknown, "json", boolean>;
405
+ readonly digest: ColumnBuilder<string | null, "text", boolean>;
406
+ readonly receipt: ColumnBuilder<unknown, "json", boolean>;
407
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
408
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
409
+ }>, true, never>];
410
+
411
+ declare interface InventoryOwner {
412
+ readonly ownerKind: 'player' | 'guild';
413
+ readonly ownerId: string;
414
+ }
415
+
416
+ declare interface InventoryReceipt {
417
+ readonly operationId: string;
418
+ readonly kind: 'grant' | 'consume' | 'equip' | 'expire' | 'craft' | 'reserve' | 'release' | 'transfer-out' | 'transfer-in';
419
+ readonly changes: readonly {
420
+ readonly instanceId: string;
421
+ readonly delta: number;
422
+ }[];
423
+ readonly at: number;
424
+ }
425
+
426
+ export declare const inventoryRecipesTable: Table<"_voltro_inv_recipes", FieldDefinitions<{
427
+ readonly id: ColumnBuilder<string, "id", boolean>;
428
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
429
+ readonly recipeId: ColumnBuilder<string, "text", boolean>;
430
+ readonly version: ColumnBuilder<number, "integer", boolean>;
431
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
432
+ readonly rulesVersion: ColumnBuilder<string, "text", boolean>;
433
+ }>, true, never>;
434
+
435
+ export declare const inventoryRecipeTables: readonly [ Table<"_voltro_inv_recipes", FieldDefinitions<{
436
+ readonly id: ColumnBuilder<string, "id", boolean>;
437
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
438
+ readonly recipeId: ColumnBuilder<string, "text", boolean>;
439
+ readonly version: ColumnBuilder<number, "integer", boolean>;
440
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
441
+ readonly rulesVersion: ColumnBuilder<string, "text", boolean>;
442
+ }>, true, never>];
443
+
444
+ declare interface InventoryRef {
445
+ readonly kind: string;
446
+ readonly id: string;
447
+ }
448
+
449
+ export declare interface InventoryReleaseInput {
450
+ readonly tenantId: string;
451
+ readonly owner: InventoryOwner;
452
+ readonly reservationId: string;
453
+ }
454
+
455
+ /** Original custody proof, separate from current availability. A redacted peer
456
+ * has no serialized receipt; its retained movement conservation is still checked. */
457
+ export declare interface InventoryReservationEvidence {
458
+ readonly reservationId: string;
459
+ readonly state: InventoryReservationView['state'];
460
+ readonly items: InventoryReservationView['items'];
461
+ readonly reserve: InventoryReceipt | null;
462
+ readonly release: InventoryReceipt | null;
463
+ readonly transfer: {
464
+ readonly from: InventoryReceipt;
465
+ readonly to: InventoryReceipt | null;
466
+ } | null;
467
+ }
468
+
469
+ export declare interface InventoryReservationTransferInput {
470
+ readonly tenantId: string;
471
+ readonly from: InventoryOwner;
472
+ readonly to: InventoryOwner;
473
+ readonly reservationId: string;
474
+ }
475
+
476
+ export declare interface InventoryReservationTransferReceipt {
477
+ readonly reservationId: string;
478
+ readonly from: InventoryReceipt;
479
+ readonly to: InventoryReceipt;
480
+ }
481
+
482
+ export declare interface InventoryReservationView {
483
+ readonly reservationId: string;
484
+ readonly state: 'not-observed' | 'reserved' | 'released' | 'transferred';
485
+ readonly items: readonly {
486
+ readonly qty: number;
487
+ readonly instance: InventoryInstance;
488
+ }[];
489
+ }
490
+
491
+ export declare interface InventoryReservedTransferReceipt {
492
+ readonly reserve: InventoryReceipt;
493
+ readonly transfer: InventoryReservationTransferReceipt;
494
+ }
495
+
496
+ /** Trusted server participant input. Selecting quantities never proves ownership. */
497
+ export declare interface InventoryReserveInput {
498
+ readonly tenantId: string;
499
+ readonly owner: InventoryOwner;
500
+ readonly reservationId: string;
501
+ readonly items: readonly {
502
+ readonly instanceId: string;
503
+ readonly qty: number;
504
+ }[];
505
+ }
506
+
507
+ export declare interface InventoryReserveTransferInput extends InventoryReservationTransferInput {
508
+ readonly items: readonly {
509
+ readonly instanceId: string;
510
+ readonly qty: number;
511
+ }[];
512
+ }
513
+
514
+ /** Installed routes and trusted callers use this same replaceable service. */
515
+ declare interface InventoryService {
516
+ readonly grant: (subject: Subject, input: InventoryGrant) => Effect.Effect<InventoryReceipt, InventoryError>;
517
+ readonly consume: (subject: Subject, input: InventoryConsume) => Effect.Effect<InventoryReceipt, InventoryError>;
518
+ readonly mine: (subject: Subject) => Effect.Effect<readonly InventoryInstance[], InventoryError>;
519
+ readonly loadout: (subject: Subject, slotSet: string) => Effect.Effect<readonly InventoryLoadout[], InventoryError>;
520
+ readonly equip: (subject: Subject, input: InventoryEquip) => Effect.Effect<InventoryReceipt, InventoryError>;
521
+ readonly expire: (subject: Subject, input: InventoryExpire) => Effect.Effect<InventoryReceipt, InventoryError>;
522
+ readonly exportSubject: (target: PluginPrivacyTarget) => Effect.Effect<unknown, InventoryError>;
523
+ readonly eraseSubject: (target: PluginPrivacyTarget) => Effect.Effect<void, InventoryError>;
524
+ }
525
+
526
+ export declare interface InventorySqlService extends InventoryService {
527
+ readonly prepareConsume: (subject: Subject, input: Parameters<InventoryService['consume']>[1]) => Effect.Effect<PreparedSqlMutation<InventoryReceipt>, InventoryError>;
528
+ readonly prepareReserveTransfer: (subject: Subject, input: InventoryReserveTransferInput) => Effect.Effect<PreparedSqlMutation<InventoryReservedTransferReceipt>, InventoryError>;
529
+ readonly prepareReservationTransfer: (subject: Subject, input: InventoryReservationTransferInput) => Effect.Effect<PreparedSqlMutation<InventoryReservationTransferReceipt>, InventoryError>;
530
+ readonly prepareReserve: (subject: Subject, input: InventoryReserveInput) => Effect.Effect<PreparedSqlMutation<InventoryReceipt>, InventoryError>;
531
+ readonly prepareRelease: (subject: Subject, input: InventoryReleaseInput) => Effect.Effect<PreparedSqlMutation<InventoryReceipt>, InventoryError>;
532
+ readonly reservation: (subject: Subject, input: InventoryReleaseInput) => Effect.Effect<InventoryReservationView, InventoryError>;
533
+ readonly reservationEvidence: (subject: Subject, input: InventoryReleaseInput) => Effect.Effect<InventoryReservationEvidence, InventoryError>;
534
+ readonly prepareGrant: (subject: Subject, input: InventoryGrant) => Effect.Effect<PreparedSqlMutation<InventoryReceipt>, InventoryError>;
535
+ readonly prepareCraft: (subject: Subject, input: CraftRequest) => Effect.Effect<PreparedSqlMutation<InventoryReceipt>, InventoryError>;
536
+ readonly craft: (subject: Subject, input: CraftRequest) => Effect.Effect<InventoryReceipt, InventoryError>;
537
+ readonly auditInventory: (subject: Subject, tenantId: string, owner: InventoryOwner) => Effect.Effect<InventoryAudit, InventoryError>;
538
+ readonly rebuildInventory: (subject: Subject, tenantId: string, owner: InventoryOwner) => Effect.Effect<InventoryAudit, InventoryError>;
539
+ }
540
+
541
+ export declare interface InventoryStoreOptions {
542
+ readonly items: readonly ItemDefinition[];
543
+ readonly catalogSource: CatalogSourceService;
544
+ readonly channel: string;
545
+ readonly locale: string;
546
+ readonly allowedServices?: readonly string[] | undefined;
547
+ readonly slotSets?: Readonly<Record<string, readonly string[]>> | undefined;
548
+ readonly maxInstances?: number | undefined;
549
+ readonly maxLedgerRows?: number | undefined;
550
+ readonly now?: (() => number) | undefined;
551
+ readonly stackPolicy?: StackPolicy | undefined;
552
+ readonly expiryPolicy?: ExpiryPolicy | undefined;
553
+ readonly crafting?: CraftingOptions | undefined;
554
+ }
555
+
556
+ export declare const inventorySubjectsTable: Table<"_voltro_inv_subjects", FieldDefinitions<{
557
+ readonly id: ColumnBuilder<string, "id", boolean>;
558
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
559
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
560
+ readonly ownerId: ColumnBuilder<string | null, "text", boolean>;
561
+ readonly erased: ColumnBuilder<boolean, "boolean", boolean>;
562
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
563
+ readonly sequence: ColumnBuilder<number, "integer", boolean>;
564
+ }>, true, never>;
565
+
566
+ export declare const inventoryTables: readonly [ Table<"_voltro_inv_catalog_locks", FieldDefinitions<{
567
+ readonly id: ColumnBuilder<string, "id", boolean>;
568
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
569
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
570
+ }>, true, never>, Table<"_voltro_inv_catalog_heads", FieldDefinitions<{
571
+ readonly id: ColumnBuilder<string, "id", boolean>;
572
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
573
+ readonly channel: ColumnBuilder<string, "text", boolean>;
574
+ readonly locale: ColumnBuilder<string, "text", boolean>;
575
+ readonly revision: ColumnBuilder<string, "text", boolean>;
576
+ readonly updatedAt: ColumnBuilder<Date, "timestamp", boolean>;
577
+ }>, true, never>, Table<"_voltro_inv_catalog", FieldDefinitions<{
578
+ readonly id: ColumnBuilder<string, "id", boolean>;
579
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
580
+ readonly revision: ColumnBuilder<string, "text", boolean>;
581
+ readonly channel: ColumnBuilder<string, "text", boolean>;
582
+ readonly locale: ColumnBuilder<string, "text", boolean>;
583
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
584
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
585
+ }>, true, never>, Table<"_voltro_inv_catalog_versions", FieldDefinitions<{
586
+ readonly id: ColumnBuilder<string, "id", boolean>;
587
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
588
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
589
+ readonly schemaVersion: ColumnBuilder<number, "integer", boolean>;
590
+ readonly kind: ColumnBuilder<string, "text", boolean>;
591
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
592
+ }>, true, never>, Table<"_voltro_inv_catalog_revisions", FieldDefinitions<{
593
+ readonly id: ColumnBuilder<string, "id", boolean>;
594
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
595
+ readonly revision: ColumnBuilder<string, "text", boolean>;
596
+ readonly channel: ColumnBuilder<string, "text", boolean>;
597
+ readonly locale: ColumnBuilder<string, "text", boolean>;
598
+ readonly digest: ColumnBuilder<string, "text", boolean>;
599
+ readonly itemCount: ColumnBuilder<number, "integer", boolean>;
600
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
601
+ }>, true, "voltro_inv_catalog_revisions_scope_idx">, Table<"_voltro_inv_subjects", FieldDefinitions<{
602
+ readonly id: ColumnBuilder<string, "id", boolean>;
603
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
604
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
605
+ readonly ownerId: ColumnBuilder<string | null, "text", boolean>;
606
+ readonly erased: ColumnBuilder<boolean, "boolean", boolean>;
607
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
608
+ readonly sequence: ColumnBuilder<number, "integer", boolean>;
609
+ }>, true, never>, Table<"_voltro_inv_items", FieldDefinitions<{
610
+ readonly id: ColumnBuilder<string, "id", boolean>;
611
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
612
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
613
+ readonly ownerId: ColumnBuilder<string, "text", boolean>;
614
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
615
+ readonly schemaVersion: ColumnBuilder<number, "integer", boolean>;
616
+ readonly qty: ColumnBuilder<number, "integer", boolean>;
617
+ readonly attributes: ColumnBuilder<unknown, "json", boolean>;
618
+ readonly acquiredAt: ColumnBuilder<Date, "timestamp", boolean>;
619
+ readonly expiresAt: ColumnBuilder<Date | null, "timestamp", boolean>;
620
+ readonly locked: ColumnBuilder<boolean, "boolean", boolean>;
621
+ readonly source: ColumnBuilder<string, "text", boolean>;
622
+ }>, true, never>, Table<"_voltro_inv_loadouts", FieldDefinitions<{
623
+ readonly id: ColumnBuilder<string, "id", boolean>;
624
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
625
+ readonly ownerKind: ColumnBuilder<"player" | "guild", "text", boolean>;
626
+ readonly ownerId: ColumnBuilder<string, "text", boolean>;
627
+ readonly slotSet: ColumnBuilder<string, "text", boolean>;
628
+ readonly slot: ColumnBuilder<string, "text", boolean>;
629
+ readonly instanceId: ColumnBuilder<string, "text", boolean>;
630
+ }>, true, never>, Table<"_voltro_inv_ledger", FieldDefinitions<{
631
+ readonly id: ColumnBuilder<string, "id", boolean>;
632
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
633
+ readonly operationId: ColumnBuilder<string, "text", boolean>;
634
+ readonly ownerKind: ColumnBuilder<"player" | "guild" | null, "text", boolean>;
635
+ readonly sequence: ColumnBuilder<number, "integer", boolean>;
636
+ readonly ownerId: ColumnBuilder<string | null, "text", boolean>;
637
+ readonly instanceId: ColumnBuilder<string | null, "text", boolean>;
638
+ readonly itemId: ColumnBuilder<string, "text", boolean>;
639
+ readonly delta: ColumnBuilder<number, "integer", boolean>;
640
+ readonly reason: ColumnBuilder<string, "text", boolean>;
641
+ readonly after: ColumnBuilder<unknown, "json", boolean>;
642
+ readonly refKind: ColumnBuilder<string | null, "text", boolean>;
643
+ readonly refId: ColumnBuilder<string | null, "text", boolean>;
644
+ readonly actor: ColumnBuilder<string | null, "text", boolean>;
645
+ readonly at: ColumnBuilder<Date, "timestamp", boolean>;
646
+ }>, true, never>, Table<"_voltro_inv_operations", FieldDefinitions<{
647
+ readonly id: ColumnBuilder<string, "id", boolean>;
648
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
649
+ readonly state: ColumnBuilder<"pending" | "erased" | "committed", "text", boolean>;
650
+ readonly ownerKey: ColumnBuilder<string | null, "text", boolean>;
651
+ readonly sequence: ColumnBuilder<number | null, "integer", boolean>;
652
+ readonly craft: ColumnBuilder<unknown, "json", boolean>;
653
+ readonly reservation: ColumnBuilder<unknown, "json", boolean>;
654
+ readonly transfer: ColumnBuilder<unknown, "json", boolean>;
655
+ readonly digest: ColumnBuilder<string | null, "text", boolean>;
656
+ readonly receipt: ColumnBuilder<unknown, "json", boolean>;
657
+ readonly admission: ColumnBuilder<number, "integer", boolean>;
658
+ readonly createdAt: ColumnBuilder<Date, "timestamp", boolean>;
659
+ }>, true, never>, Table<"_voltro_inv_recipes", FieldDefinitions<{
660
+ readonly id: ColumnBuilder<string, "id", boolean>;
661
+ readonly tenantId: ColumnBuilder<string, "text", boolean>;
662
+ readonly recipeId: ColumnBuilder<string, "text", boolean>;
663
+ readonly version: ColumnBuilder<number, "integer", boolean>;
664
+ readonly definition: ColumnBuilder<unknown, "json", boolean>;
665
+ readonly rulesVersion: ColumnBuilder<string, "text", boolean>;
666
+ }>, true, never>];
667
+
668
+ declare const ITEM_KINDS: readonly ["consumable", "equipment", "cosmetic", "currencyBundle", "key", "mod"];
669
+
670
+ declare interface ItemContract extends Omit<ItemDefinition, 'schemaVersion' | 'equipSlot' | 'expiresAfter' | 'display'> {
671
+ readonly schemaVersion: number;
672
+ readonly equipSlot: string | null;
673
+ readonly expiresAfter: number | null;
674
+ readonly display: {
675
+ readonly nameKey: string;
676
+ readonly icon: string | null;
677
+ };
678
+ }
679
+
680
+ declare interface ItemDefinition {
681
+ readonly id: string;
682
+ readonly kind: ItemKind;
683
+ readonly schemaVersion?: number;
684
+ readonly stackable: boolean;
685
+ readonly maxStack: number;
686
+ readonly tradable: boolean;
687
+ readonly rarity: string;
688
+ readonly tags: readonly string[];
689
+ readonly attributes: Schema.Top;
690
+ readonly instanceAttributes: Schema.Top;
691
+ readonly equipSlot?: string | null;
692
+ /** Milliseconds; resolved on grant, never by a tick. */
693
+ readonly expiresAfter?: number | null;
694
+ readonly display: {
695
+ readonly nameKey: string;
696
+ readonly icon?: string | null;
697
+ };
698
+ }
699
+
700
+ declare type ItemKind = typeof ITEM_KINDS[number];
701
+
702
+ declare type JsonValue = null | boolean | number | string | readonly JsonValue[] | {
703
+ readonly [key: string]: JsonValue;
704
+ };
705
+
706
+ declare interface Recipe {
707
+ readonly id: string;
708
+ readonly version: number;
709
+ readonly inputs: readonly RecipeIngredient[];
710
+ readonly outputs: readonly RecipeOutput[];
711
+ readonly maxBatches: number;
712
+ readonly cost: RecipeCurrencyCost | null;
713
+ readonly timeMs: 0;
714
+ readonly requires: null;
715
+ }
716
+
717
+ declare interface RecipeCurrencyCost {
718
+ readonly currency: string;
719
+ readonly amount: string;
720
+ }
721
+
722
+ declare interface RecipeDefinition {
723
+ readonly id: string;
724
+ readonly version?: number;
725
+ readonly inputs: readonly RecipeIngredient[];
726
+ readonly outputs: readonly RecipeOutput[];
727
+ readonly maxBatches?: number;
728
+ readonly cost?: RecipeCurrencyCost | null;
729
+ readonly timeMs?: 0;
730
+ readonly requires?: null;
731
+ }
732
+
733
+ declare interface RecipeIngredient {
734
+ readonly itemId: string;
735
+ readonly qty: number;
736
+ }
737
+
738
+ declare interface RecipeOutput extends RecipeIngredient {
739
+ readonly attributes?: JsonValue;
740
+ }
741
+
742
+ export declare const resolveInventoryOptions: (input: InventoryStoreOptions) => Readonly<{
743
+ items: readonly ItemContract[];
744
+ catalogSource: Readonly<{
745
+ read: (scope: CatalogScope) => Effect.Effect< CatalogSnapshot, InventoryError>;
746
+ }>;
747
+ channel: string;
748
+ locale: string;
749
+ slotSets: Readonly<Record<string, readonly string[]>>;
750
+ allowedServices: readonly string[];
751
+ maxInstances: number;
752
+ maxLedgerRows: number;
753
+ crafting: Readonly<{
754
+ economy: Readonly<{
755
+ prepareTransfer: (subject: Subject, input: {
756
+ readonly tenantId: string;
757
+ readonly requestId: string;
758
+ readonly currency: string;
759
+ readonly amount: string;
760
+ readonly from: {
761
+ readonly kind: "wallet";
762
+ readonly ownerKind: "player" | "guild";
763
+ readonly ownerId: string;
764
+ };
765
+ readonly to: {
766
+ readonly kind: "system";
767
+ readonly id: string;
768
+ };
769
+ readonly reason: string;
770
+ readonly ref: {
771
+ readonly kind: string;
772
+ readonly id: string;
773
+ };
774
+ }) => Effect.Effect<PreparedSqlMutation< CraftPaymentReceipt>, {
775
+ readonly code: string;
776
+ }>;
777
+ }> | undefined;
778
+ systemAccount: string | undefined;
779
+ recipes: readonly Recipe[];
780
+ craftResolver: CraftResolver;
781
+ version: string;
782
+ service: CraftingService | undefined;
783
+ }> | undefined;
784
+ now: () => number;
785
+ stackPolicy: StackPolicy;
786
+ expiryPolicy: ExpiryPolicy;
787
+ }>;
788
+
789
+ export declare interface SqlCatalogOptions {
790
+ readonly items: readonly ItemDefinition[];
791
+ readonly allowedServices?: readonly string[];
792
+ readonly maxCatalogItems?: number;
793
+ readonly maxCatalogVersions?: number;
794
+ readonly now?: () => number;
795
+ }
796
+
797
+ declare interface StackInput {
798
+ readonly item: CatalogItem;
799
+ readonly quantity: number;
800
+ readonly available: readonly {
801
+ readonly id: string;
802
+ readonly quantity: number;
803
+ }[];
804
+ }
805
+
806
+ declare interface StackPlan {
807
+ readonly existing: readonly {
808
+ readonly id: string;
809
+ readonly add: number;
810
+ }[];
811
+ readonly create: readonly number[];
812
+ }
813
+
814
+ declare type StackPolicy = (input: StackInput) => StackPlan;
815
+
816
+ export { }