@byearlybird/starling 0.11.1 → 0.12.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.
@@ -144,7 +144,7 @@ function computeResourceLatest(eventstamps, deletedAt, fallback) {
144
144
  if (deletedAt && deletedAt > max) return deletedAt;
145
145
  return max;
146
146
  }
147
- function makeResource(type, id, obj, eventstamp, deletedAt = null) {
147
+ function makeResource(id, obj, eventstamp, deletedAt = null) {
148
148
  const eventstamps = {};
149
149
  const traverse = (input, path = "") => {
150
150
  for (const key in input) {
@@ -157,7 +157,6 @@ function makeResource(type, id, obj, eventstamp, deletedAt = null) {
157
157
  };
158
158
  traverse(obj);
159
159
  return {
160
- type,
161
160
  id,
162
161
  attributes: obj,
163
162
  meta: {
@@ -193,7 +192,6 @@ function mergeResources(into, from) {
193
192
  const mergedDeletedAt = into.meta.deletedAt && from.meta.deletedAt ? into.meta.deletedAt > from.meta.deletedAt ? into.meta.deletedAt : from.meta.deletedAt : into.meta.deletedAt || from.meta.deletedAt || null;
194
193
  const finalLatest = mergedDeletedAt && mergedDeletedAt > dataLatest ? mergedDeletedAt : dataLatest;
195
194
  return {
196
- type: into.type,
197
195
  id: into.id,
198
196
  attributes: resultAttributes,
199
197
  meta: {
@@ -207,7 +205,6 @@ function deleteResource(resource, eventstamp) {
207
205
  const dataLatest = resource.meta.deletedAt ? computeResourceLatest(resource.meta.eventstamps, null) : resource.meta.latest;
208
206
  const latest = eventstamp > dataLatest ? eventstamp : dataLatest;
209
207
  return {
210
- type: resource.type,
211
208
  id: resource.id,
212
209
  attributes: resource.attributes,
213
210
  meta: {
@@ -221,7 +218,7 @@ function deleteResource(resource, eventstamp) {
221
218
  //#endregion
222
219
  //#region src/core/document/document.ts
223
220
  /**
224
- * Merges two JSON:API documents using field-level Last-Write-Wins semantics.
221
+ * Merges two Starling documents using field-level Last-Write-Wins semantics.
225
222
  *
226
223
  * The merge operation:
227
224
  * 1. Forwards the clock to the newest eventstamp from either document
@@ -239,45 +236,42 @@ function deleteResource(resource, eventstamp) {
239
236
  * @example
240
237
  * ```typescript
241
238
  * const into = {
242
- * jsonapi: { version: "1.1" },
243
- * meta: { latest: "2025-01-01T00:00:00.000Z|0001|a1b2" },
244
- * data: [{ type: "items", id: "doc1", attributes: {...}, meta: { deletedAt: null, latest: "..." } }]
239
+ * type: "items",
240
+ * latest: "2025-01-01T00:00:00.000Z|0001|a1b2",
241
+ * resources: { "doc1": { id: "doc1", attributes: {...}, meta: {...} } }
245
242
  * };
246
243
  *
247
244
  * const from = {
248
- * jsonapi: { version: "1.1" },
249
- * meta: { latest: "2025-01-01T00:05:00.000Z|0001|c3d4" },
250
- * data: [
251
- * { type: "items", id: "doc1", attributes: {...}, meta: { deletedAt: null, latest: "..." } }, // updated
252
- * { type: "items", id: "doc2", attributes: {...}, meta: { deletedAt: null, latest: "..." } } // new
253
- * ]
245
+ * type: "items",
246
+ * latest: "2025-01-01T00:05:00.000Z|0001|c3d4",
247
+ * resources: {
248
+ * "doc1": { id: "doc1", attributes: {...}, meta: {...} }, // updated
249
+ * "doc2": { id: "doc2", attributes: {...}, meta: {...} } // new
250
+ * }
254
251
  * };
255
252
  *
256
253
  * const result = mergeDocuments(into, from);
257
- * // result.document.meta.latest === "2025-01-01T00:05:00.000Z|0001|c3d4"
254
+ * // result.document.latest === "2025-01-01T00:05:00.000Z|0001|c3d4"
258
255
  * // result.changes.added has "doc2"
259
256
  * // result.changes.updated has "doc1"
260
257
  * ```
261
258
  */
262
259
  function mergeDocuments(into, from) {
263
- const intoDocsById = /* @__PURE__ */ new Map();
264
- for (const doc of into.data) intoDocsById.set(doc.id, doc);
265
260
  const added = /* @__PURE__ */ new Map();
266
261
  const updated = /* @__PURE__ */ new Map();
267
262
  const deleted = /* @__PURE__ */ new Set();
268
- const mergedDocsById = new Map(intoDocsById);
269
- let newestEventstamp = into.meta.latest >= from.meta.latest ? into.meta.latest : from.meta.latest;
270
- for (const fromDoc of from.data) {
271
- const id = fromDoc.id;
272
- const intoDoc = intoDocsById.get(id);
263
+ const mergedResources = { ...into.resources };
264
+ let newestEventstamp = into.latest >= from.latest ? into.latest : from.latest;
265
+ for (const [id, fromDoc] of Object.entries(from.resources)) {
266
+ const intoDoc = into.resources[id];
273
267
  if (!intoDoc) {
274
- mergedDocsById.set(id, fromDoc);
268
+ mergedResources[id] = fromDoc;
275
269
  if (!fromDoc.meta.deletedAt) added.set(id, fromDoc);
276
270
  if (fromDoc.meta.latest > newestEventstamp) newestEventstamp = fromDoc.meta.latest;
277
271
  } else {
278
272
  if (intoDoc === fromDoc) continue;
279
273
  const mergedDoc = mergeResources(intoDoc, fromDoc);
280
- mergedDocsById.set(id, mergedDoc);
274
+ mergedResources[id] = mergedDoc;
281
275
  if (mergedDoc.meta.latest > newestEventstamp) newestEventstamp = mergedDoc.meta.latest;
282
276
  const wasDeleted = intoDoc.meta.deletedAt !== null;
283
277
  const isDeleted = mergedDoc.meta.deletedAt !== null;
@@ -289,9 +283,9 @@ function mergeDocuments(into, from) {
289
283
  }
290
284
  return {
291
285
  document: {
292
- jsonapi: { version: "1.1" },
293
- meta: { latest: newestEventstamp },
294
- data: Array.from(mergedDocsById.values())
286
+ type: into.type,
287
+ latest: newestEventstamp,
288
+ resources: mergedResources
295
289
  },
296
290
  changes: {
297
291
  added,
@@ -301,49 +295,53 @@ function mergeDocuments(into, from) {
301
295
  };
302
296
  }
303
297
  /**
304
- * Creates an empty JSON:API document with the given eventstamp.
298
+ * Creates an empty Starling document with the given type and eventstamp.
305
299
  * Useful for initializing new stores or testing.
306
300
  *
301
+ * @param type - Resource type identifier for this collection
307
302
  * @param eventstamp - Initial clock value for this document
308
303
  * @returns Empty document
309
304
  *
310
305
  * @example
311
306
  * ```typescript
312
- * const empty = makeDocument("2025-01-01T00:00:00.000Z|0000|0000");
307
+ * const empty = makeDocument("tasks", "2025-01-01T00:00:00.000Z|0000|0000");
313
308
  * ```
314
309
  */
315
- function makeDocument(eventstamp) {
310
+ function makeDocument(type, eventstamp) {
316
311
  return {
317
- jsonapi: { version: "1.1" },
318
- meta: { latest: eventstamp },
319
- data: []
312
+ type,
313
+ latest: eventstamp,
314
+ resources: {}
320
315
  };
321
316
  }
322
317
 
323
318
  //#endregion
324
319
  //#region src/core/document/utils.ts
325
320
  /**
326
- * Convert a JsonDocument's data array into a Map keyed by resource ID.
327
- * @param document - JsonDocument containing resource data
321
+ * Convert a StarlingDocument's resources into a Map keyed by resource ID.
322
+ * @param document - StarlingDocument containing resource data
328
323
  * @returns Map of resource ID to ResourceObject
329
324
  */
330
325
  function documentToMap(document) {
331
- return new Map(document.data.map((doc) => [doc.id, doc]));
326
+ return new Map(Object.entries(document.resources));
332
327
  }
333
328
  /**
334
- * Convert a Map of resources into a JsonDocument.
329
+ * Convert a Map of resources into a StarlingDocument.
330
+ * @param type - Resource type identifier for this collection
335
331
  * @param resources - Map of resource ID to ResourceObject
336
332
  * @param fallbackEventstamp - Eventstamp to include when computing the max (optional)
337
- * @returns JsonDocument representation of the resources
333
+ * @returns StarlingDocument representation of the resources
338
334
  */
339
- function mapToDocument(resources, fallbackEventstamp) {
340
- const resourceArray = Array.from(resources.values());
341
- const eventstamps = resourceArray.map((r) => r.meta.latest);
335
+ function mapToDocument(type, resources, fallbackEventstamp) {
336
+ const eventstamps = Array.from(resources.values()).map((r) => r.meta.latest);
342
337
  if (fallbackEventstamp) eventstamps.push(fallbackEventstamp);
338
+ const latest = maxEventstamp(eventstamps);
339
+ const resourcesRecord = {};
340
+ for (const [id, resource] of resources) resourcesRecord[id] = resource;
343
341
  return {
344
- jsonapi: { version: "1.1" },
345
- meta: { latest: maxEventstamp(eventstamps) },
346
- data: resourceArray
342
+ type,
343
+ latest,
344
+ resources: resourcesRecord
347
345
  };
348
346
  }
349
347
 
@@ -382,7 +380,7 @@ function createMap(resourceType, initialMap = /* @__PURE__ */ new Map(), eventst
382
380
  return internalMap.entries();
383
381
  },
384
382
  set(id, object) {
385
- const encoded = makeResource(resourceType, id, object, clock.now());
383
+ const encoded = makeResource(id, object, clock.now());
386
384
  const current = internalMap.get(id);
387
385
  if (current) {
388
386
  const merged = mergeResources(current, encoded);
@@ -400,23 +398,22 @@ function createMap(resourceType, initialMap = /* @__PURE__ */ new Map(), eventst
400
398
  return new Map(internalMap);
401
399
  },
402
400
  toDocument() {
403
- return mapToDocument(internalMap, clock.latest());
401
+ return mapToDocument(resourceType, internalMap, clock.latest());
404
402
  },
405
403
  merge(document) {
406
- const result = mergeDocuments(mapToDocument(internalMap, clock.latest()), document);
407
- clock.forward(result.document.meta.latest);
404
+ const result = mergeDocuments(mapToDocument(resourceType, internalMap, clock.latest()), document);
405
+ clock.forward(result.document.latest);
408
406
  internalMap = documentToMap(result.document);
409
407
  return result;
410
408
  }
411
409
  };
412
410
  }
413
411
  /**
414
- * Create a ResourceMap from a JsonDocument snapshot.
415
- * @param type - Resource type identifier (defaults to "default")
416
- * @param document - JsonDocument containing resource data
412
+ * Create a ResourceMap from a StarlingDocument snapshot.
413
+ * @param document - StarlingDocument containing resource data
417
414
  */
418
- function createMapFromDocument(type, document) {
419
- return createMap(document.data[0]?.type ?? type, documentToMap(document), document.meta.latest);
415
+ function createMapFromDocument(document) {
416
+ return createMap(document.type, documentToMap(document), document.latest);
420
417
  }
421
418
 
422
419
  //#endregion
package/dist/core.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as maxEventstamp, a as AnyObject, b as createClock, c as MergeDocumentsResult, d as ResourceObject, f as deleteResource, g as isValidEventstamp, h as MIN_EVENTSTAMP, i as mapToDocument, l as makeDocument, m as mergeResources, n as createMapFromDocument, o as DocumentChanges, p as makeResource, r as documentToMap, s as JsonDocument, t as createMap, u as mergeDocuments, v as InvalidEventstampError, x as createClockFromEventstamp, y as Clock } from "./index-D7bXWDg6.js";
2
- export { AnyObject, Clock, DocumentChanges, InvalidEventstampError, JsonDocument, MIN_EVENTSTAMP, MergeDocumentsResult, ResourceObject, createClock, createClockFromEventstamp, createMap, createMapFromDocument, deleteResource, documentToMap, isValidEventstamp, makeDocument, makeResource, mapToDocument, maxEventstamp, mergeDocuments, mergeResources };
1
+ import { _ as maxEventstamp, a as AnyObject, b as createClock, c as StarlingDocument, d as ResourceObject, f as deleteResource, g as isValidEventstamp, h as MIN_EVENTSTAMP, i as mapToDocument, l as makeDocument, m as mergeResources, n as createMapFromDocument, o as DocumentChanges, p as makeResource, r as documentToMap, s as MergeDocumentsResult, t as createMap, u as mergeDocuments, v as InvalidEventstampError, x as createClockFromEventstamp, y as Clock } from "./index-BIpu-1zO.js";
2
+ export { AnyObject, Clock, DocumentChanges, InvalidEventstampError, MIN_EVENTSTAMP, MergeDocumentsResult, ResourceObject, StarlingDocument, createClock, createClockFromEventstamp, createMap, createMapFromDocument, deleteResource, documentToMap, isValidEventstamp, makeDocument, makeResource, mapToDocument, maxEventstamp, mergeDocuments, mergeResources };
package/dist/core.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as makeDocument, c as makeResource, d as createClockFromEventstamp, f as MIN_EVENTSTAMP, h as InvalidEventstampError, i as mapToDocument, l as mergeResources, m as maxEventstamp, n as createMapFromDocument, o as mergeDocuments, p as isValidEventstamp, r as documentToMap, s as deleteResource, t as createMap, u as createClock } from "./core-DI0FfUjX.js";
1
+ import { a as makeDocument, c as makeResource, d as createClockFromEventstamp, f as MIN_EVENTSTAMP, h as InvalidEventstampError, i as mapToDocument, l as mergeResources, m as maxEventstamp, n as createMapFromDocument, o as mergeDocuments, p as isValidEventstamp, r as documentToMap, s as deleteResource, t as createMap, u as createClock } from "./core-UUzgRHaU.js";
2
2
 
3
3
  export { InvalidEventstampError, MIN_EVENTSTAMP, createClock, createClockFromEventstamp, createMap, createMapFromDocument, deleteResource, documentToMap, isValidEventstamp, makeDocument, makeResource, mapToDocument, maxEventstamp, mergeDocuments, mergeResources };
@@ -1,4 +1,4 @@
1
- import { a as AnyObject, s as JsonDocument } from "./index-D7bXWDg6.js";
1
+ import { a as AnyObject, c as StarlingDocument } from "./index-BIpu-1zO.js";
2
2
 
3
3
  //#region src/database/standard-schema.d.ts
4
4
  /** The Standard Schema interface. */
@@ -104,8 +104,8 @@ type Collection<T extends AnyObjectSchema> = {
104
104
  add(item: StandardSchemaV1.InferInput<T>): InferData<T>;
105
105
  update(id: string, updates: Partial<StandardSchemaV1.InferInput<T>>): void;
106
106
  remove(id: string): void;
107
- merge(document: JsonDocument<InferData<T>>): void;
108
- toDocument(): JsonDocument<InferData<T>>;
107
+ merge(document: StarlingDocument<InferData<T>>): void;
108
+ toDocument(): StarlingDocument<InferData<T>>;
109
109
  on(event: "mutation", handler: (payload: CollectionMutationEvent<InferData<T>>) => void): () => void;
110
110
  };
111
111
  declare class IdNotFoundError extends Error {
@@ -165,7 +165,7 @@ type Database<Schemas extends SchemasMap> = Collections<Schemas> & {
165
165
  version: number;
166
166
  begin<R>(callback: (tx: TransactionContext<Schemas>) => R): R;
167
167
  query<R>(callback: (ctx: QueryContext<Schemas>) => R): QueryHandle<R>;
168
- toDocuments(): { [K in keyof Schemas]: JsonDocument<StandardSchemaV1.InferOutput<Schemas[K]>> };
168
+ toDocuments(): { [K in keyof Schemas]: StarlingDocument<StandardSchemaV1.InferOutput<Schemas[K]>> };
169
169
  on(event: "mutation", handler: (payload: DatabaseMutationEvent<Schemas>) => unknown): () => void;
170
170
  use(plugin: DatabasePlugin<Schemas>): Database<Schemas>;
171
171
  init(): Promise<Database<Schemas>>;
@@ -196,4 +196,4 @@ type Database<Schemas extends SchemasMap> = Collections<Schemas> & {
196
196
  */
197
197
  declare function createDatabase<Schemas extends SchemasMap>(config: DbConfig<Schemas>): Database<Schemas>;
198
198
  //#endregion
199
- export { StandardSchemaV1 as _, createDatabase as a, QueryCollectionHandle as c, Collection as d, CollectionInternals as f, SchemasMap as g, AnyObjectSchema as h, DbConfig as i, QueryContext as l, IdNotFoundError as m, Database as n, TransactionCollectionHandle as o, DuplicateIdError as p, DatabasePlugin as r, TransactionContext as s, CollectionConfig as t, QueryHandle as u };
199
+ export { createDatabase as a, QueryCollectionHandle as c, Collection as d, CollectionInternals as f, StandardSchemaV1 as g, SchemasMap as h, DbConfig as i, QueryContext as l, IdNotFoundError as m, Database as n, TransactionCollectionHandle as o, DuplicateIdError as p, DatabasePlugin as r, TransactionContext as s, CollectionConfig as t, QueryHandle as u };
@@ -62,12 +62,11 @@ declare function maxEventstamp(eventstamps: string[]): string;
62
62
  * Resource object structure representing a single stored entity.
63
63
  * Resources are the primary unit of storage and synchronization in Starling.
64
64
  *
65
- * Each resource has a type, unique identifier, attributes containing the data,
65
+ * Each resource has a unique identifier, attributes containing the data,
66
66
  * and metadata for tracking deletion state and eventstamps.
67
+ * The resource type is stored at the document level.
67
68
  */
68
69
  type ResourceObject<T extends AnyObject> = {
69
- /** Resource type identifier */
70
- type: string;
71
70
  /** Unique identifier for this resource */
72
71
  id: string;
73
72
  /** The resource's data as a nested object structure */
@@ -82,7 +81,7 @@ type ResourceObject<T extends AnyObject> = {
82
81
  deletedAt: string | null;
83
82
  };
84
83
  };
85
- declare function makeResource<T extends AnyObject>(type: string, id: string, obj: T, eventstamp: string, deletedAt?: string | null): ResourceObject<T>;
84
+ declare function makeResource<T extends AnyObject>(id: string, obj: T, eventstamp: string, deletedAt?: string | null): ResourceObject<T>;
86
85
  declare function mergeResources<T extends AnyObject>(into: ResourceObject<T>, from: ResourceObject<T>): ResourceObject<T>;
87
86
  declare function deleteResource<T extends AnyObject>(resource: ResourceObject<T>, eventstamp: string): ResourceObject<T>;
88
87
  //#endregion
@@ -93,25 +92,20 @@ declare function deleteResource<T extends AnyObject>(resource: ResourceObject<T>
93
92
  */
94
93
  type AnyObject = Record<string, unknown>;
95
94
  /**
96
- * A JSON:API document represents the complete state of a store:
97
- * - API version information
98
- * - Metadata including the highest eventstamp observed across all operations
99
- * - A set of resource objects (including soft-deleted ones)
95
+ * A Starling document represents the complete state of a collection:
96
+ * - Resource type identifier
97
+ * - Latest eventstamp for clock synchronization
98
+ * - Map of resources keyed by ID
100
99
  *
101
- * Documents are the unit of synchronization between store replicas.
100
+ * Documents are the unit of synchronization between replicas.
102
101
  */
103
- type JsonDocument<T extends AnyObject> = {
104
- /** API version information */
105
- jsonapi: {
106
- version: "1.1";
107
- };
108
- /** Document-level metadata */
109
- meta: {
110
- /** Latest eventstamp observed by this document for clock synchronization */
111
- latest: string;
112
- };
113
- /** Array of resource objects with eventstamps and metadata */
114
- data: ResourceObject<T>[];
102
+ type StarlingDocument<T extends AnyObject> = {
103
+ /** Resource type for this homogeneous collection */
104
+ type: string;
105
+ /** Latest eventstamp observed by this document for clock synchronization */
106
+ latest: string;
107
+ /** Map of resources keyed by ID for efficient lookups */
108
+ resources: Record<string, ResourceObject<T>>;
115
109
  };
116
110
  /**
117
111
  * Change tracking information returned by mergeDocuments.
@@ -126,16 +120,16 @@ type DocumentChanges<T extends AnyObject> = {
126
120
  deleted: Set<string>;
127
121
  };
128
122
  /**
129
- * Result of merging two JSON:API documents.
123
+ * Result of merging two Starling documents.
130
124
  */
131
125
  type MergeDocumentsResult<T extends AnyObject> = {
132
126
  /** The merged document with updated resources and forwarded clock */
133
- document: JsonDocument<T>;
127
+ document: StarlingDocument<T>;
134
128
  /** Change tracking for plugin hook notifications */
135
129
  changes: DocumentChanges<T>;
136
130
  };
137
131
  /**
138
- * Merges two JSON:API documents using field-level Last-Write-Wins semantics.
132
+ * Merges two Starling documents using field-level Last-Write-Wins semantics.
139
133
  *
140
134
  * The merge operation:
141
135
  * 1. Forwards the clock to the newest eventstamp from either document
@@ -153,55 +147,57 @@ type MergeDocumentsResult<T extends AnyObject> = {
153
147
  * @example
154
148
  * ```typescript
155
149
  * const into = {
156
- * jsonapi: { version: "1.1" },
157
- * meta: { latest: "2025-01-01T00:00:00.000Z|0001|a1b2" },
158
- * data: [{ type: "items", id: "doc1", attributes: {...}, meta: { deletedAt: null, latest: "..." } }]
150
+ * type: "items",
151
+ * latest: "2025-01-01T00:00:00.000Z|0001|a1b2",
152
+ * resources: { "doc1": { id: "doc1", attributes: {...}, meta: {...} } }
159
153
  * };
160
154
  *
161
155
  * const from = {
162
- * jsonapi: { version: "1.1" },
163
- * meta: { latest: "2025-01-01T00:05:00.000Z|0001|c3d4" },
164
- * data: [
165
- * { type: "items", id: "doc1", attributes: {...}, meta: { deletedAt: null, latest: "..." } }, // updated
166
- * { type: "items", id: "doc2", attributes: {...}, meta: { deletedAt: null, latest: "..." } } // new
167
- * ]
156
+ * type: "items",
157
+ * latest: "2025-01-01T00:05:00.000Z|0001|c3d4",
158
+ * resources: {
159
+ * "doc1": { id: "doc1", attributes: {...}, meta: {...} }, // updated
160
+ * "doc2": { id: "doc2", attributes: {...}, meta: {...} } // new
161
+ * }
168
162
  * };
169
163
  *
170
164
  * const result = mergeDocuments(into, from);
171
- * // result.document.meta.latest === "2025-01-01T00:05:00.000Z|0001|c3d4"
165
+ * // result.document.latest === "2025-01-01T00:05:00.000Z|0001|c3d4"
172
166
  * // result.changes.added has "doc2"
173
167
  * // result.changes.updated has "doc1"
174
168
  * ```
175
169
  */
176
- declare function mergeDocuments<T extends AnyObject>(into: JsonDocument<T>, from: JsonDocument<T>): MergeDocumentsResult<T>;
170
+ declare function mergeDocuments<T extends AnyObject>(into: StarlingDocument<T>, from: StarlingDocument<T>): MergeDocumentsResult<T>;
177
171
  /**
178
- * Creates an empty JSON:API document with the given eventstamp.
172
+ * Creates an empty Starling document with the given type and eventstamp.
179
173
  * Useful for initializing new stores or testing.
180
174
  *
175
+ * @param type - Resource type identifier for this collection
181
176
  * @param eventstamp - Initial clock value for this document
182
177
  * @returns Empty document
183
178
  *
184
179
  * @example
185
180
  * ```typescript
186
- * const empty = makeDocument("2025-01-01T00:00:00.000Z|0000|0000");
181
+ * const empty = makeDocument("tasks", "2025-01-01T00:00:00.000Z|0000|0000");
187
182
  * ```
188
183
  */
189
- declare function makeDocument<T extends AnyObject>(eventstamp: string): JsonDocument<T>;
184
+ declare function makeDocument<T extends AnyObject>(type: string, eventstamp: string): StarlingDocument<T>;
190
185
  //#endregion
191
186
  //#region src/core/document/utils.d.ts
192
187
  /**
193
- * Convert a JsonDocument's data array into a Map keyed by resource ID.
194
- * @param document - JsonDocument containing resource data
188
+ * Convert a StarlingDocument's resources into a Map keyed by resource ID.
189
+ * @param document - StarlingDocument containing resource data
195
190
  * @returns Map of resource ID to ResourceObject
196
191
  */
197
- declare function documentToMap<T extends AnyObject>(document: JsonDocument<T>): Map<string, ResourceObject<T>>;
192
+ declare function documentToMap<T extends AnyObject>(document: StarlingDocument<T>): Map<string, ResourceObject<T>>;
198
193
  /**
199
- * Convert a Map of resources into a JsonDocument.
194
+ * Convert a Map of resources into a StarlingDocument.
195
+ * @param type - Resource type identifier for this collection
200
196
  * @param resources - Map of resource ID to ResourceObject
201
197
  * @param fallbackEventstamp - Eventstamp to include when computing the max (optional)
202
- * @returns JsonDocument representation of the resources
198
+ * @returns StarlingDocument representation of the resources
203
199
  */
204
- declare function mapToDocument<T extends AnyObject>(resources: Map<string, ResourceObject<T>>, fallbackEventstamp?: string): JsonDocument<T>;
200
+ declare function mapToDocument<T extends AnyObject>(type: string, resources: Map<string, ResourceObject<T>>, fallbackEventstamp?: string): StarlingDocument<T>;
205
201
  //#endregion
206
202
  //#region src/core/resource-map/resource-map.d.ts
207
203
  /**
@@ -250,21 +246,20 @@ declare function createMap<T extends AnyObject>(resourceType: string, initialMap
250
246
  */
251
247
  cloneMap(): Map<string, ResourceObject<T>>;
252
248
  /**
253
- * Export the current state as a JsonDocument snapshot.
249
+ * Export the current state as a StarlingDocument snapshot.
254
250
  */
255
- toDocument(): JsonDocument<T>;
251
+ toDocument(): StarlingDocument<T>;
256
252
  /**
257
253
  * Merge another document into this ResourceMap using field-level Last-Write-Wins.
258
254
  * @returns The merge result containing the merged document and tracked changes
259
- * @param document - JsonDocument from another replica or storage
255
+ * @param document - StarlingDocument from another replica or storage
260
256
  */
261
- merge(document: JsonDocument<T>): MergeDocumentsResult<T>;
257
+ merge(document: StarlingDocument<T>): MergeDocumentsResult<T>;
262
258
  };
263
259
  /**
264
- * Create a ResourceMap from a JsonDocument snapshot.
265
- * @param type - Resource type identifier (defaults to "default")
266
- * @param document - JsonDocument containing resource data
260
+ * Create a ResourceMap from a StarlingDocument snapshot.
261
+ * @param document - StarlingDocument containing resource data
267
262
  */
268
- declare function createMapFromDocument<U extends AnyObject>(type: string, document: JsonDocument<U>): ReturnType<typeof createMap<U>>;
263
+ declare function createMapFromDocument<U extends AnyObject>(document: StarlingDocument<U>): ReturnType<typeof createMap<U>>;
269
264
  //#endregion
270
- export { maxEventstamp as _, AnyObject as a, createClock as b, MergeDocumentsResult as c, ResourceObject as d, deleteResource as f, isValidEventstamp as g, MIN_EVENTSTAMP as h, mapToDocument as i, makeDocument as l, mergeResources as m, createMapFromDocument as n, DocumentChanges as o, makeResource as p, documentToMap as r, JsonDocument as s, createMap as t, mergeDocuments as u, InvalidEventstampError as v, createClockFromEventstamp as x, Clock as y };
265
+ export { maxEventstamp as _, AnyObject as a, createClock as b, StarlingDocument as c, ResourceObject as d, deleteResource as f, isValidEventstamp as g, MIN_EVENTSTAMP as h, mapToDocument as i, makeDocument as l, mergeResources as m, createMapFromDocument as n, DocumentChanges as o, makeResource as p, documentToMap as r, MergeDocumentsResult as s, createMap as t, mergeDocuments as u, InvalidEventstampError as v, createClockFromEventstamp as x, Clock as y };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { a as AnyObject, s as JsonDocument } from "./index-D7bXWDg6.js";
2
- import { _ as StandardSchemaV1, a as createDatabase, c as QueryCollectionHandle, d as Collection, f as CollectionInternals, g as SchemasMap, h as AnyObjectSchema, i as DbConfig, l as QueryContext, m as IdNotFoundError, n as Database, o as TransactionCollectionHandle, p as DuplicateIdError, r as DatabasePlugin, s as TransactionContext, t as CollectionConfig, u as QueryHandle } from "./db-DJ_6dO-K.js";
3
- export { type AnyObject, AnyObjectSchema, type Collection, type CollectionConfig, CollectionInternals, type Database, type DatabasePlugin, type DbConfig, DuplicateIdError, IdNotFoundError, type JsonDocument, type QueryCollectionHandle, type QueryContext, type QueryHandle, SchemasMap, type StandardSchemaV1, type TransactionCollectionHandle, type TransactionContext, createDatabase };
1
+ import { a as AnyObject, c as StarlingDocument } from "./index-BIpu-1zO.js";
2
+ import { a as createDatabase, c as QueryCollectionHandle, d as Collection, f as CollectionInternals, g as StandardSchemaV1, i as DbConfig, l as QueryContext, m as IdNotFoundError, n as Database, o as TransactionCollectionHandle, p as DuplicateIdError, r as DatabasePlugin, s as TransactionContext, t as CollectionConfig, u as QueryHandle } from "./db-DY3UcmfV.js";
3
+ export { type AnyObject, type Collection, type CollectionConfig, CollectionInternals, type Database, type DatabasePlugin, type DbConfig, DuplicateIdError, IdNotFoundError, type QueryCollectionHandle, type QueryContext, type QueryHandle, type StandardSchemaV1, type StarlingDocument, type TransactionCollectionHandle, type TransactionContext, createDatabase };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as makeResource, i as mapToDocument, l as mergeResources, o as mergeDocuments, s as deleteResource, u as createClock } from "./core-DI0FfUjX.js";
1
+ import { c as makeResource, i as mapToDocument, l as mergeResources, o as mergeDocuments, s as deleteResource, u as createClock } from "./core-UUzgRHaU.js";
2
2
 
3
3
  //#region src/database/emitter.ts
4
4
  function createEmitter() {
@@ -98,7 +98,7 @@ function createCollection(name, schema, getId, getEventstamp, initialData, optio
98
98
  const validated = standardValidate(schema, item);
99
99
  const id = getId(validated);
100
100
  if (data.has(id)) throw new DuplicateIdError(id);
101
- const resource = makeResource(name, id, validated, getEventstamp());
101
+ const resource = makeResource(id, validated, getEventstamp());
102
102
  data.set(id, resource);
103
103
  pendingMutations.added.push({
104
104
  id,
@@ -111,7 +111,7 @@ function createCollection(name, schema, getId, getEventstamp, initialData, optio
111
111
  const existing = data.get(id);
112
112
  if (!existing) throw new IdNotFoundError(id);
113
113
  const before = existing.attributes;
114
- const merged = mergeResources(existing, makeResource(name, id, updates, getEventstamp()));
114
+ const merged = mergeResources(existing, makeResource(id, updates, getEventstamp()));
115
115
  standardValidate(schema, merged.attributes);
116
116
  data.set(id, merged);
117
117
  pendingMutations.updated.push({
@@ -136,9 +136,9 @@ function createCollection(name, schema, getId, getEventstamp, initialData, optio
136
136
  merge(document) {
137
137
  const beforeState = /* @__PURE__ */ new Map();
138
138
  for (const [id, resource] of data.entries()) beforeState.set(id, resource.attributes);
139
- const result = mergeDocuments(mapToDocument(data, getEventstamp()), document);
139
+ const result = mergeDocuments(mapToDocument(name, data, getEventstamp()), document);
140
140
  data.clear();
141
- for (const resource of result.document.data) data.set(resource.id, resource);
141
+ for (const [id, resource] of Object.entries(result.document.resources)) data.set(id, resource);
142
142
  for (const [id, resource] of result.changes.added) {
143
143
  standardValidate(schema, resource.attributes);
144
144
  pendingMutations.added.push({
@@ -165,7 +165,7 @@ function createCollection(name, schema, getId, getEventstamp, initialData, optio
165
165
  if (autoFlush) flushMutations();
166
166
  },
167
167
  toDocument() {
168
- return mapToDocument(data, getEventstamp());
168
+ return mapToDocument(name, data, getEventstamp());
169
169
  },
170
170
  on(event, handler) {
171
171
  return emitter.on(event, handler);
@@ -1,5 +1,5 @@
1
- import { a as AnyObject, s as JsonDocument } from "./index-D7bXWDg6.js";
2
- import { g as SchemasMap, r as DatabasePlugin } from "./db-DJ_6dO-K.js";
1
+ import { a as AnyObject, c as StarlingDocument } from "./index-BIpu-1zO.js";
2
+ import { h as SchemasMap, r as DatabasePlugin } from "./db-DY3UcmfV.js";
3
3
 
4
4
  //#region src/plugins/http/index.d.ts
5
5
 
@@ -10,7 +10,7 @@ type RequestContext<T extends AnyObject = AnyObject> = {
10
10
  collection: string;
11
11
  operation: "GET" | "PATCH";
12
12
  url: string;
13
- document?: JsonDocument<T>;
13
+ document?: StarlingDocument<T>;
14
14
  };
15
15
  /**
16
16
  * Result returned by the onRequest hook
@@ -19,13 +19,13 @@ type RequestHookResult<T extends AnyObject = AnyObject> = {
19
19
  skip: true;
20
20
  } | {
21
21
  headers?: Record<string, string>;
22
- document?: JsonDocument<T>;
22
+ document?: StarlingDocument<T>;
23
23
  } | undefined;
24
24
  /**
25
25
  * Result returned by the onResponse hook
26
26
  */
27
27
  type ResponseHookResult<T extends AnyObject = AnyObject> = {
28
- document: JsonDocument<T>;
28
+ document: StarlingDocument<T>;
29
29
  } | {
30
30
  skip: true;
31
31
  } | undefined;
@@ -61,7 +61,7 @@ type HttpPluginConfig<_Schemas extends SchemasMap> = {
61
61
  */
62
62
  onResponse?: <T extends AnyObject>(context: {
63
63
  collection: string;
64
- document: JsonDocument<T>;
64
+ document: StarlingDocument<T>;
65
65
  }) => ResponseHookResult<T>;
66
66
  /**
67
67
  * Retry configuration for failed requests
@@ -1,5 +1,5 @@
1
- import "./index-D7bXWDg6.js";
2
- import { r as DatabasePlugin } from "./db-DJ_6dO-K.js";
1
+ import "./index-BIpu-1zO.js";
2
+ import { r as DatabasePlugin } from "./db-DY3UcmfV.js";
3
3
 
4
4
  //#region src/plugins/idb/index.d.ts
5
5
  type IdbPluginConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byearlybird/starling",
3
- "version": "0.11.1",
3
+ "version": "0.12.0",
4
4
  "description": "Local-first data sync for JavaScript apps. Typed collections, transactions, and automatic conflict resolution.",
5
5
  "type": "module",
6
6
  "license": "MIT",