@starkeep/protocol-primitives 0.1.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/LICENSE +21 -0
- package/README.md +107 -0
- package/dist/index.cjs +627 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +316 -0
- package/dist/index.d.ts +316 -0
- package/dist/index.js +594 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
|
|
3
|
+
type StarkeepId = string & {
|
|
4
|
+
readonly __brand: unique symbol;
|
|
5
|
+
};
|
|
6
|
+
declare function createStarkeepId(value: string): StarkeepId;
|
|
7
|
+
declare function isStarkeepId(value: unknown): value is StarkeepId;
|
|
8
|
+
|
|
9
|
+
declare function generateId(): StarkeepId;
|
|
10
|
+
declare function generateIdAt(timestamp: number): StarkeepId;
|
|
11
|
+
|
|
12
|
+
interface HLCTimestamp {
|
|
13
|
+
readonly wallTime: number;
|
|
14
|
+
readonly counter: number;
|
|
15
|
+
readonly nodeId: string;
|
|
16
|
+
}
|
|
17
|
+
interface HLCClock {
|
|
18
|
+
now(): HLCTimestamp;
|
|
19
|
+
send(): HLCTimestamp;
|
|
20
|
+
receive(remote: HLCTimestamp): HLCTimestamp;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface ClockState {
|
|
24
|
+
wallTime: number;
|
|
25
|
+
counter: number;
|
|
26
|
+
}
|
|
27
|
+
interface ClockOptions {
|
|
28
|
+
nodeId: string;
|
|
29
|
+
wallClockFunction?: () => number;
|
|
30
|
+
/**
|
|
31
|
+
* Pre-seed the clock from persisted state so a post-restart HLC never
|
|
32
|
+
* emits a timestamp earlier than one the node already sent.
|
|
33
|
+
*/
|
|
34
|
+
initialState?: ClockState;
|
|
35
|
+
/**
|
|
36
|
+
* Invoked on every state change. Callers typically debounce and persist
|
|
37
|
+
* to a SyncStateStore.
|
|
38
|
+
*/
|
|
39
|
+
onTick?: (state: ClockState) => void;
|
|
40
|
+
}
|
|
41
|
+
declare function createHLCClock(options: ClockOptions): HLCClock;
|
|
42
|
+
|
|
43
|
+
/** Identity element for HLC ordering. Useful as a default watermark / "never seen". */
|
|
44
|
+
declare const ZERO_HLC: HLCTimestamp;
|
|
45
|
+
declare function compareHLC(a: HLCTimestamp, b: HLCTimestamp): -1 | 0 | 1;
|
|
46
|
+
declare function maxHLC(a: HLCTimestamp, b: HLCTimestamp): HLCTimestamp;
|
|
47
|
+
|
|
48
|
+
declare function serializeHLC(timestamp: HLCTimestamp): string;
|
|
49
|
+
declare function deserializeHLC(serializedString: string): HLCTimestamp;
|
|
50
|
+
|
|
51
|
+
interface BaseRecord {
|
|
52
|
+
readonly id: StarkeepId;
|
|
53
|
+
/**
|
|
54
|
+
* The record's lowercase file extension, verbatim (e.g. "jpg", "md", "xyz");
|
|
55
|
+
* "" for extension-less files. This is the identification key. The derived
|
|
56
|
+
* category (`categoryOf(type)`) determines the metadata table and storage
|
|
57
|
+
* prefix; unmapped/empty extensions derive category "other".
|
|
58
|
+
*/
|
|
59
|
+
readonly type: string;
|
|
60
|
+
readonly createdAt: HLCTimestamp;
|
|
61
|
+
updatedAt: HLCTimestamp;
|
|
62
|
+
readonly ownerId: string;
|
|
63
|
+
deletedAt: HLCTimestamp | null;
|
|
64
|
+
version: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A row in the shared records table. Every DataRecord is backed by a file in
|
|
68
|
+
* object storage (`objectStorageKey` + `contentHash`); metadata derived from
|
|
69
|
+
* the file lives in the per-category `record_<category>_metadata` table
|
|
70
|
+
* (category = `categoryOf(type)`; `other` records have no metadata table).
|
|
71
|
+
*
|
|
72
|
+
* App-level / user-authored fields that cannot be deterministically derived
|
|
73
|
+
* from the file (titles, captions, edit provenance, etc.) live in app-private
|
|
74
|
+
* storage, not on this row.
|
|
75
|
+
*/
|
|
76
|
+
interface DataRecord extends BaseRecord {
|
|
77
|
+
readonly kind: "data";
|
|
78
|
+
contentHash: string;
|
|
79
|
+
objectStorageKey: string;
|
|
80
|
+
mimeType: string;
|
|
81
|
+
sizeBytes: number;
|
|
82
|
+
originalFilename: string | null;
|
|
83
|
+
/**
|
|
84
|
+
* App identity that produced this record. Set by the data-server at write
|
|
85
|
+
* time from the authenticated subject. Required on every write.
|
|
86
|
+
*/
|
|
87
|
+
originAppId: string;
|
|
88
|
+
/**
|
|
89
|
+
* Optional parent record id linking this record to another shared record
|
|
90
|
+
* (e.g. a thumbnail's parent is its original). The parent may be of any
|
|
91
|
+
* type; cross-type parent links are permitted.
|
|
92
|
+
*/
|
|
93
|
+
parentId: StarkeepId | null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* One row in a per-category metadata table (`shared_record_<category>_metadata`
|
|
97
|
+
* / `shared.record_<category>_metadata`). Columns are declared by the
|
|
98
|
+
* category's entry in `CATEGORIES`. Every column other than `recordId` must be
|
|
99
|
+
* deterministically derivable from the record's file bytes.
|
|
100
|
+
*/
|
|
101
|
+
interface MetadataRow {
|
|
102
|
+
recordId: StarkeepId;
|
|
103
|
+
[column: string]: unknown;
|
|
104
|
+
}
|
|
105
|
+
type AnyRecord = DataRecord;
|
|
106
|
+
|
|
107
|
+
interface CreateDataRecordInput {
|
|
108
|
+
type: string;
|
|
109
|
+
ownerId: string;
|
|
110
|
+
originAppId: string;
|
|
111
|
+
contentHash: string;
|
|
112
|
+
objectStorageKey: string;
|
|
113
|
+
mimeType: string;
|
|
114
|
+
sizeBytes: number;
|
|
115
|
+
originalFilename?: string | null;
|
|
116
|
+
parentId?: StarkeepId | null;
|
|
117
|
+
}
|
|
118
|
+
declare function createDataRecord(input: CreateDataRecordInput, clock: HLCClock): DataRecord;
|
|
119
|
+
|
|
120
|
+
interface TypeDefinition {
|
|
121
|
+
name: string;
|
|
122
|
+
namespace: string;
|
|
123
|
+
schema: v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>;
|
|
124
|
+
}
|
|
125
|
+
interface TypeRegistry {
|
|
126
|
+
register(definition: TypeDefinition): void;
|
|
127
|
+
get(namespace: string, name: string): TypeDefinition | undefined;
|
|
128
|
+
getByKey(key: string): TypeDefinition | undefined;
|
|
129
|
+
has(namespace: string, name: string): boolean;
|
|
130
|
+
list(): TypeDefinition[];
|
|
131
|
+
}
|
|
132
|
+
declare function createTypeRegistry(): TypeRegistry;
|
|
133
|
+
|
|
134
|
+
declare const dataRecordSchema: v.ObjectSchema<{
|
|
135
|
+
readonly kind: v.LiteralSchema<"data", undefined>;
|
|
136
|
+
readonly contentHash: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
137
|
+
readonly objectStorageKey: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
138
|
+
readonly mimeType: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
139
|
+
readonly sizeBytes: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
140
|
+
readonly originalFilename: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
141
|
+
readonly originAppId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
142
|
+
readonly parentId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
143
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 26, undefined>]>;
|
|
144
|
+
readonly type: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
145
|
+
readonly createdAt: v.ObjectSchema<{
|
|
146
|
+
readonly wallTime: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
147
|
+
readonly counter: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
148
|
+
readonly nodeId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
149
|
+
}, undefined>;
|
|
150
|
+
readonly updatedAt: v.ObjectSchema<{
|
|
151
|
+
readonly wallTime: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
152
|
+
readonly counter: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
153
|
+
readonly nodeId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
154
|
+
}, undefined>;
|
|
155
|
+
readonly ownerId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
156
|
+
readonly deletedAt: v.NullableSchema<v.ObjectSchema<{
|
|
157
|
+
readonly wallTime: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
158
|
+
readonly counter: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
159
|
+
readonly nodeId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
160
|
+
}, undefined>, undefined>;
|
|
161
|
+
readonly version: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
162
|
+
}, undefined>;
|
|
163
|
+
declare function validateDataRecord(data: unknown): v.SafeParseResult<v.ObjectSchema<{
|
|
164
|
+
readonly kind: v.LiteralSchema<"data", undefined>;
|
|
165
|
+
readonly contentHash: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
166
|
+
readonly objectStorageKey: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
167
|
+
readonly mimeType: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
168
|
+
readonly sizeBytes: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
169
|
+
readonly originalFilename: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
170
|
+
readonly originAppId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
171
|
+
readonly parentId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
172
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 26, undefined>]>;
|
|
173
|
+
readonly type: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
174
|
+
readonly createdAt: v.ObjectSchema<{
|
|
175
|
+
readonly wallTime: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
176
|
+
readonly counter: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
177
|
+
readonly nodeId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
178
|
+
}, undefined>;
|
|
179
|
+
readonly updatedAt: v.ObjectSchema<{
|
|
180
|
+
readonly wallTime: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
181
|
+
readonly counter: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
182
|
+
readonly nodeId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
183
|
+
}, undefined>;
|
|
184
|
+
readonly ownerId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
185
|
+
readonly deletedAt: v.NullableSchema<v.ObjectSchema<{
|
|
186
|
+
readonly wallTime: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
187
|
+
readonly counter: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
188
|
+
readonly nodeId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
|
|
189
|
+
}, undefined>, undefined>;
|
|
190
|
+
readonly version: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
191
|
+
}, undefined>>;
|
|
192
|
+
|
|
193
|
+
declare class StarkeepError extends Error {
|
|
194
|
+
readonly code: string;
|
|
195
|
+
readonly cause?: unknown | undefined;
|
|
196
|
+
constructor(message: string, code: string, cause?: unknown | undefined);
|
|
197
|
+
}
|
|
198
|
+
declare class ValidationError extends StarkeepError {
|
|
199
|
+
constructor(message: string, cause?: unknown);
|
|
200
|
+
}
|
|
201
|
+
declare class NotFoundError extends StarkeepError {
|
|
202
|
+
constructor(entity: string, id: string);
|
|
203
|
+
}
|
|
204
|
+
declare class ConflictError extends StarkeepError {
|
|
205
|
+
constructor(message: string);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
type Result<T, E = Error> = {
|
|
209
|
+
ok: true;
|
|
210
|
+
value: T;
|
|
211
|
+
} | {
|
|
212
|
+
ok: false;
|
|
213
|
+
error: E;
|
|
214
|
+
};
|
|
215
|
+
declare function ok<T>(value: T): Result<T, never>;
|
|
216
|
+
declare function err<E>(error: E): Result<never, E>;
|
|
217
|
+
interface PaginationOptions {
|
|
218
|
+
limit: number;
|
|
219
|
+
cursor?: string;
|
|
220
|
+
}
|
|
221
|
+
interface PaginatedResult<T> {
|
|
222
|
+
items: T[];
|
|
223
|
+
nextCursor: string | null;
|
|
224
|
+
hasMore: boolean;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Single source of truth for Starkeep's shared core type system.
|
|
229
|
+
*
|
|
230
|
+
* Two registries derived from one place:
|
|
231
|
+
* - EXTENSIONS: lowercase file extension → mapped Category. Identification is
|
|
232
|
+
* by extension; MIME is never authoritative.
|
|
233
|
+
* - CATEGORIES: the user-facing organizational layer (mobile-style: Images,
|
|
234
|
+
* Videos, Documents…). Each mapped category owns one metadata table holding
|
|
235
|
+
* cross-format properties derivable from the file bytes.
|
|
236
|
+
*
|
|
237
|
+
* A record's `type` is the lowercase extension verbatim (e.g. "jpg", "md",
|
|
238
|
+
* "xyz"), even when the extension is unmapped. Its category is derived:
|
|
239
|
+
* `category = EXTENSIONS[ext] ?? "other"`. `other` is the terminal catch-all
|
|
240
|
+
* for unmapped / extension-less files — Drive-only, no metadata table, and no
|
|
241
|
+
* installable app can ever be granted it (apps may only declare extensions that
|
|
242
|
+
* are present in EXTENSIONS, and the unmapped set IS the `other` set).
|
|
243
|
+
*
|
|
244
|
+
* Every relevant system — manifest validation, IAM emission, DSQL schema-init,
|
|
245
|
+
* SQLite bootstrap, object-key construction, and the local data-server's access
|
|
246
|
+
* path — derives its view from the registries below. Adding an extension or a
|
|
247
|
+
* metadata column is a one-file edit here. There is no runtime registration
|
|
248
|
+
* path — apps cannot register new types or extend metadata columns.
|
|
249
|
+
*/
|
|
250
|
+
type LogicalColumnType = "integer" | "bigint" | "real" | "text" | "timestamp" | "boolean";
|
|
251
|
+
interface CoreTypeMetadataColumn {
|
|
252
|
+
name: string;
|
|
253
|
+
type: LogicalColumnType;
|
|
254
|
+
/** Defaults to true. Set explicitly when the column must be NOT NULL. */
|
|
255
|
+
nullable?: boolean;
|
|
256
|
+
}
|
|
257
|
+
/** The fixed set of categories. `other` is the terminal catch-all (last). */
|
|
258
|
+
type Category = "image" | "video" | "audio" | "document" | "text" | "code" | "font" | "archive" | "data" | "model3d" | "other";
|
|
259
|
+
interface CategoryDef {
|
|
260
|
+
id: Category;
|
|
261
|
+
description: string;
|
|
262
|
+
/** Cross-format metadata columns. Empty for `other` (no metadata table). */
|
|
263
|
+
metadataColumns: CoreTypeMetadataColumn[];
|
|
264
|
+
}
|
|
265
|
+
declare const CATEGORIES: readonly CategoryDef[];
|
|
266
|
+
/**
|
|
267
|
+
* Extension (lowercase, no dot) → mapped category. `other` is NEVER a value
|
|
268
|
+
* here — it is exclusively the `?? "other"` fallback in `categoryOf`, which is
|
|
269
|
+
* why no app can ever declare an `other` extension.
|
|
270
|
+
*/
|
|
271
|
+
declare const EXTENSIONS: Readonly<Record<string, Exclude<Category, "other">>>;
|
|
272
|
+
declare const CATEGORY_IDS: readonly Category[];
|
|
273
|
+
/**
|
|
274
|
+
* Categories an installable app may be granted — every category a real
|
|
275
|
+
* extension can map to, i.e. all categories EXCEPT `other`. Drive's all-access
|
|
276
|
+
* (`fileAccessAll`) covers `other` as well, via its `shared/*` IAM ceiling.
|
|
277
|
+
*/
|
|
278
|
+
declare const APP_GRANTABLE_CATEGORIES: readonly Category[];
|
|
279
|
+
/** The set of known (mapped) extensions. */
|
|
280
|
+
declare const KNOWN_EXTENSIONS: ReadonlySet<string>;
|
|
281
|
+
/**
|
|
282
|
+
* Derived category for a record's extension/type. Unmapped or empty → "other".
|
|
283
|
+
* Accepts the extension with or without a leading dot, any case.
|
|
284
|
+
*/
|
|
285
|
+
declare function categoryOf(ext: string): Category;
|
|
286
|
+
declare function getCategory(id: string): CategoryDef | undefined;
|
|
287
|
+
declare function isCategoryId(id: string): id is Category;
|
|
288
|
+
/**
|
|
289
|
+
* Emits a `CREATE TABLE IF NOT EXISTS shared.record_<category>_metadata`
|
|
290
|
+
* statement for DSQL. Single non-PL/pgSQL statement, no FK constraints — see
|
|
291
|
+
* `dsql-schema-init.ts` for the DSQL surface caveats. Callers must skip the
|
|
292
|
+
* `other` category (no metadata table).
|
|
293
|
+
*/
|
|
294
|
+
declare function pgMetadataDdl(c: CategoryDef): string;
|
|
295
|
+
/**
|
|
296
|
+
* Emits a `CREATE TABLE IF NOT EXISTS shared_record_<category>_metadata`
|
|
297
|
+
* statement for the local SQLite bootstrap. Callers must skip the `other`
|
|
298
|
+
* category (no metadata table).
|
|
299
|
+
*/
|
|
300
|
+
declare function sqliteMetadataDdl(c: CategoryDef): string;
|
|
301
|
+
/**
|
|
302
|
+
* Returns the SQLite metadata table name for a record's type/extension or a
|
|
303
|
+
* category id. The category is derived when an extension is passed, so storage
|
|
304
|
+
* adapters that hold only `record.type` route to the correct per-category
|
|
305
|
+
* table. Passing the literal `"other"` (or an unmapped extension) yields the
|
|
306
|
+
* `other` table name, which is never created — callers must not write metadata
|
|
307
|
+
* for `other` records.
|
|
308
|
+
*/
|
|
309
|
+
declare function sqliteMetadataTableName(typeOrCategory: string): string;
|
|
310
|
+
/** DSQL/Postgres counterpart of {@link sqliteMetadataTableName}. */
|
|
311
|
+
declare function pgMetadataTableName(typeOrCategory: string): string;
|
|
312
|
+
|
|
313
|
+
declare function dataRecordObjectKey(typeOrExt: string, contentHash: string): string;
|
|
314
|
+
declare function appSyncableObjectKey(appId: string, subKey: string): string;
|
|
315
|
+
|
|
316
|
+
export { APP_GRANTABLE_CATEGORIES, type AnyRecord, type BaseRecord, CATEGORIES, CATEGORY_IDS, type Category, type CategoryDef, type ClockOptions, ConflictError, type CoreTypeMetadataColumn, type CreateDataRecordInput, type DataRecord, EXTENSIONS, type HLCClock, type HLCTimestamp, KNOWN_EXTENSIONS, type LogicalColumnType, type MetadataRow, NotFoundError, type PaginatedResult, type PaginationOptions, type Result, StarkeepError, type StarkeepId, type TypeDefinition, type TypeRegistry, ValidationError, ZERO_HLC, appSyncableObjectKey, categoryOf, compareHLC, createDataRecord, createHLCClock, createStarkeepId, createTypeRegistry, dataRecordObjectKey, dataRecordSchema, deserializeHLC, err, generateId, generateIdAt, getCategory, isCategoryId, isStarkeepId, maxHLC, ok, pgMetadataDdl, pgMetadataTableName, serializeHLC, sqliteMetadataDdl, sqliteMetadataTableName, validateDataRecord };
|