@palantir/pack.state.core 0.0.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/.turbo/turbo-lint.log +4 -0
  2. package/.turbo/turbo-transpileBrowser.log +5 -0
  3. package/.turbo/turbo-transpileCjs.log +5 -0
  4. package/.turbo/turbo-transpileEsm.log +5 -0
  5. package/.turbo/turbo-transpileTypes.log +5 -0
  6. package/.turbo/turbo-typecheck.log +4 -0
  7. package/LICENSE.txt +13 -0
  8. package/README.md +55 -0
  9. package/build/browser/index.js +1257 -0
  10. package/build/browser/index.js.map +1 -0
  11. package/build/cjs/index.cjs +1298 -0
  12. package/build/cjs/index.cjs.map +1 -0
  13. package/build/cjs/index.d.cts +272 -0
  14. package/build/esm/index.js +1257 -0
  15. package/build/esm/index.js.map +1 -0
  16. package/build/types/DocumentServiceModule.d.ts +6 -0
  17. package/build/types/DocumentServiceModule.d.ts.map +1 -0
  18. package/build/types/__tests__/DocumentStatusTracking.test.d.ts +1 -0
  19. package/build/types/__tests__/DocumentStatusTracking.test.d.ts.map +1 -0
  20. package/build/types/__tests__/RefStability.test.d.ts +1 -0
  21. package/build/types/__tests__/RefStability.test.d.ts.map +1 -0
  22. package/build/types/__tests__/StateModule.integration.test.d.ts +1 -0
  23. package/build/types/__tests__/StateModule.integration.test.d.ts.map +1 -0
  24. package/build/types/__tests__/testUtils.d.ts +7 -0
  25. package/build/types/__tests__/testUtils.d.ts.map +1 -0
  26. package/build/types/index.d.ts +11 -0
  27. package/build/types/index.d.ts.map +1 -0
  28. package/build/types/service/BaseYjsDocumentService.d.ts +155 -0
  29. package/build/types/service/BaseYjsDocumentService.d.ts.map +1 -0
  30. package/build/types/service/InMemoryDocumentService.d.ts +12 -0
  31. package/build/types/service/InMemoryDocumentService.d.ts.map +1 -0
  32. package/build/types/service/YjsSchemaMapper.d.ts +9 -0
  33. package/build/types/service/YjsSchemaMapper.d.ts.map +1 -0
  34. package/build/types/types/DocumentRefImpl.d.ts +5 -0
  35. package/build/types/types/DocumentRefImpl.d.ts.map +1 -0
  36. package/build/types/types/DocumentService.d.ts +62 -0
  37. package/build/types/types/DocumentService.d.ts.map +1 -0
  38. package/build/types/types/DocumentServiceConfig.d.ts +5 -0
  39. package/build/types/types/DocumentServiceConfig.d.ts.map +1 -0
  40. package/build/types/types/RecordCollectionRefImpl.d.ts +5 -0
  41. package/build/types/types/RecordCollectionRefImpl.d.ts.map +1 -0
  42. package/build/types/types/RecordRefImpl.d.ts +5 -0
  43. package/build/types/types/RecordRefImpl.d.ts.map +1 -0
  44. package/build/types/types/StateModule.d.ts +59 -0
  45. package/build/types/types/StateModule.d.ts.map +1 -0
  46. package/package.json +71 -0
  47. package/src/DocumentServiceModule.ts +53 -0
  48. package/src/__tests__/DocumentStatusTracking.test.ts +229 -0
  49. package/src/__tests__/RefStability.test.ts +441 -0
  50. package/src/__tests__/StateModule.integration.test.ts +1187 -0
  51. package/src/__tests__/testUtils.ts +106 -0
  52. package/src/index.ts +38 -0
  53. package/src/service/BaseYjsDocumentService.ts +1277 -0
  54. package/src/service/InMemoryDocumentService.ts +162 -0
  55. package/src/service/YjsSchemaMapper.ts +194 -0
  56. package/src/types/DocumentRefImpl.ts +98 -0
  57. package/src/types/DocumentService.ts +210 -0
  58. package/src/types/DocumentServiceConfig.ts +22 -0
  59. package/src/types/RecordCollectionRefImpl.ts +124 -0
  60. package/src/types/RecordRefImpl.ts +106 -0
  61. package/src/types/StateModule.ts +329 -0
  62. package/tsconfig.json +21 -0
  63. package/vitest.config.mjs +26 -0
@@ -0,0 +1,124 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type {
18
+ DocumentRef,
19
+ Model,
20
+ ModelData,
21
+ RecordCollectionRef,
22
+ RecordId,
23
+ RecordRef,
24
+ Unsubscribe,
25
+ } from "@palantir/pack.document-schema.model-types";
26
+ import { RecordCollectionRefBrand } from "@palantir/pack.document-schema.model-types";
27
+ import { invalidDocRef } from "./DocumentRefImpl.js";
28
+ import type { DocumentService } from "./DocumentService.js";
29
+
30
+ const INVALID_RECORD_COLLECTION_REF: RecordCollectionRef = Object.freeze(
31
+ {
32
+ docRef: invalidDocRef(),
33
+ model: {} as Model,
34
+ [RecordCollectionRefBrand]: RecordCollectionRefBrand,
35
+ get: () => undefined,
36
+ has: () => false,
37
+ set: () => Promise.reject(new Error("Invalid record collection reference")),
38
+ delete: () => Promise.reject(new Error("Invalid record collection reference")),
39
+ size: 0,
40
+ [Symbol.iterator]: () => ({
41
+ next: () => ({ done: true as const, value: undefined as never }),
42
+ }),
43
+ onItemsAdded: () => () => {},
44
+ onItemsChanged: () => () => {},
45
+ onItemsDeleted: () => () => {},
46
+ } as const,
47
+ );
48
+
49
+ export const createRecordCollectionRef = <const M extends Model>(
50
+ documentService: DocumentService,
51
+ docRef: DocumentRef,
52
+ model: M,
53
+ ): RecordCollectionRef<M> => {
54
+ return new RecordCollectionRefImpl(documentService, docRef, model);
55
+ };
56
+
57
+ export function invalidRecordCollectionRef<M extends Model = Model>(): RecordCollectionRef<M> {
58
+ return INVALID_RECORD_COLLECTION_REF as RecordCollectionRef<M>;
59
+ }
60
+
61
+ export function isValidRecordCollectionRef<M extends Model = Model>(
62
+ collectionRef: RecordCollectionRef<M>,
63
+ ): collectionRef is RecordCollectionRef<M> {
64
+ return collectionRef !== INVALID_RECORD_COLLECTION_REF;
65
+ }
66
+
67
+ class RecordCollectionRefImpl<M extends Model> implements RecordCollectionRef<M> {
68
+ readonly docRef: DocumentRef;
69
+ readonly model: M;
70
+ declare readonly [RecordCollectionRefBrand]: typeof RecordCollectionRefBrand;
71
+ readonly #documentService: DocumentService;
72
+
73
+ constructor(documentService: DocumentService, docRef: DocumentRef, model: M) {
74
+ this.docRef = docRef;
75
+ this.model = model;
76
+ this.#documentService = documentService;
77
+ }
78
+
79
+ get(id: RecordId): RecordRef<M> | undefined {
80
+ return this.#documentService.getRecord(this, id);
81
+ }
82
+
83
+ has(id: RecordId): boolean {
84
+ return this.#documentService.hasRecord(this, id);
85
+ }
86
+
87
+ async set(id: RecordId, state: ModelData<M>): Promise<void> {
88
+ return this.#documentService.setCollectionRecord(this, id, state);
89
+ }
90
+
91
+ delete(id: RecordId): Promise<void> {
92
+ const recordRefInstance = this.#documentService.getRecord(this, id);
93
+ if (recordRefInstance) {
94
+ return this.#documentService.deleteRecord(recordRefInstance);
95
+ }
96
+ return Promise.reject(new Error(`Unknown record`));
97
+ }
98
+
99
+ get size(): number {
100
+ return this.#documentService.getCollectionSize(this);
101
+ }
102
+
103
+ [Symbol.iterator](): Iterator<RecordRef<M>> {
104
+ return this.#documentService.getCollectionRecords(this)[Symbol.iterator]();
105
+ }
106
+
107
+ readonly onItemsAdded = (
108
+ callback: (items: readonly RecordRef<M>[]) => void,
109
+ ): Unsubscribe => {
110
+ return this.#documentService.onCollectionItemsAdded(this, callback);
111
+ };
112
+
113
+ readonly onItemsChanged = (
114
+ callback: (items: readonly RecordRef<M>[]) => void,
115
+ ): Unsubscribe => {
116
+ return this.#documentService.onCollectionItemsChanged(this, callback);
117
+ };
118
+
119
+ readonly onItemsDeleted = (
120
+ callback: (items: readonly RecordRef<M>[]) => void,
121
+ ): Unsubscribe => {
122
+ return this.#documentService.onCollectionItemsDeleted(this, callback);
123
+ };
124
+ }
@@ -0,0 +1,106 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type {
18
+ DocumentRef,
19
+ Model,
20
+ ModelData,
21
+ RecordId,
22
+ RecordRef,
23
+ Unsubscribe,
24
+ } from "@palantir/pack.document-schema.model-types";
25
+ import { RecordRefBrand } from "@palantir/pack.document-schema.model-types";
26
+ import { invalidDocRef } from "./DocumentRefImpl.js";
27
+ import type { DocumentService } from "./DocumentService.js";
28
+
29
+ const INVALID_RECORD_ID: RecordId = "INVALID_RECORD_REF";
30
+ const INVALID_RECORD_REF: RecordRef = Object.freeze(
31
+ {
32
+ docRef: invalidDocRef(),
33
+ id: INVALID_RECORD_ID,
34
+ model: {} as Model,
35
+ [RecordRefBrand]: RecordRefBrand,
36
+ getSnapshot: () => Promise.reject(new Error("Invalid record reference")),
37
+ set: () => Promise.reject(new Error("Invalid record reference")),
38
+ onChange: () => () => {},
39
+ onDeleted: () => () => {},
40
+ } as const,
41
+ );
42
+
43
+ export const createRecordRef = <const M extends Model>(
44
+ documentService: DocumentService,
45
+ docRef: DocumentRef,
46
+ id: RecordId,
47
+ model: M,
48
+ ): RecordRef<M> => {
49
+ return new RecordRefImpl(documentService, docRef, id, model);
50
+ };
51
+
52
+ export function invalidRecordRef<M extends Model = Model>(): RecordRef<M> {
53
+ return INVALID_RECORD_REF as RecordRef<M>;
54
+ }
55
+
56
+ export function isValidRecordRef<M extends Model = Model>(
57
+ recordRef: RecordRef<M>,
58
+ ): recordRef is RecordRef<M> {
59
+ return recordRef.id !== INVALID_RECORD_ID;
60
+ }
61
+
62
+ class RecordRefImpl<M extends Model> implements RecordRef<M> {
63
+ readonly docRef: DocumentRef;
64
+ readonly id: RecordId;
65
+ readonly model: M;
66
+ declare readonly [RecordRefBrand]: typeof RecordRefBrand;
67
+ readonly #documentService: DocumentService;
68
+
69
+ constructor(
70
+ documentService: DocumentService,
71
+ docRef: DocumentRef,
72
+ id: RecordId,
73
+ model: M,
74
+ ) {
75
+ this.#documentService = documentService;
76
+ this.docRef = docRef;
77
+ this.id = id;
78
+ this.model = model;
79
+ }
80
+
81
+ async getSnapshot(): Promise<ModelData<M>> {
82
+ return this.#documentService.getRecordSnapshot(this);
83
+ }
84
+
85
+ onChange(
86
+ callback: (snapshot: ModelData<M>, recordRef: RecordRef<M>) => void,
87
+ ): Unsubscribe {
88
+ return this.#documentService.onRecordChanged(this, callback);
89
+ }
90
+
91
+ onDeleted(callback: (recordRef: RecordRef<M>) => void): Unsubscribe {
92
+ return this.#documentService.onRecordDeleted(this, callback);
93
+ }
94
+
95
+ delete(): Promise<void> {
96
+ return this.#documentService.deleteRecord(this);
97
+ }
98
+
99
+ set(record: ModelData<M>): Promise<void> {
100
+ return this.#documentService.setRecord(this, record);
101
+ }
102
+
103
+ update(partialRecord: Partial<ModelData<M>>): Promise<void> {
104
+ return this.#documentService.updateRecord(this, partialRecord);
105
+ }
106
+ }
@@ -0,0 +1,329 @@
1
+ /*
2
+ * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ assertIsAppInternal,
19
+ type ModuleKey,
20
+ type PackAppInternal,
21
+ type Unsubscribe,
22
+ } from "@palantir/pack.core";
23
+ import type {
24
+ DocumentId,
25
+ DocumentMetadata,
26
+ DocumentRef,
27
+ DocumentSchema,
28
+ DocumentState,
29
+ Model,
30
+ ModelData,
31
+ RecordCollectionRef,
32
+ RecordId,
33
+ RecordRef,
34
+ } from "@palantir/pack.document-schema.model-types";
35
+ import { DOCUMENT_SERVICE_MODULE_KEY } from "../DocumentServiceModule.js";
36
+ import type {
37
+ DocumentService,
38
+ RecordChangeCallback,
39
+ RecordCollectionChangeCallback,
40
+ RecordDeleteCallback,
41
+ } from "./DocumentService.js";
42
+
43
+ // Ensure state module is accessible on PackApp instances.
44
+ export const STATE_MODULE_ACCESSOR = "state";
45
+ export const STATE_MODULE_KEY: ModuleKey<StateModuleImpl> = {
46
+ appMemberName: STATE_MODULE_ACCESSOR,
47
+ key: Symbol.for("pack.state"),
48
+ initModule: (app: PackAppInternal) => {
49
+ const documentService = app.getModule(DOCUMENT_SERVICE_MODULE_KEY);
50
+ return new StateModuleImpl(documentService);
51
+ },
52
+ };
53
+ export type WithStateModule<T> = T & { readonly [STATE_MODULE_ACCESSOR]: StateModule };
54
+
55
+ export interface StateModule {
56
+ readonly createDocRef: <const T extends DocumentSchema>(
57
+ id: DocumentId,
58
+ schema: T,
59
+ ) => DocumentRef<T>;
60
+
61
+ readonly createRecordRef: <const M extends Model>(
62
+ docRef: DocumentRef,
63
+ id: RecordId,
64
+ model: M,
65
+ ) => RecordRef<M>;
66
+
67
+ readonly createDocument: <T extends DocumentSchema>(
68
+ metadata: DocumentMetadata,
69
+ schema: T,
70
+ ) => Promise<DocumentRef<T>>;
71
+
72
+ readonly getDocumentSnapshot: <T extends DocumentSchema>(
73
+ docRef: DocumentRef<T>,
74
+ ) => Promise<DocumentState<T>>;
75
+
76
+ readonly onMetadataChange: <T extends DocumentSchema>(
77
+ docRef: DocumentRef<T>,
78
+ cb: (docRef: DocumentRef<T>, metadata: DocumentMetadata) => void,
79
+ ) => Unsubscribe;
80
+
81
+ readonly onStateChange: <T extends DocumentSchema>(
82
+ docRef: DocumentRef<T>,
83
+ cb: (docRef: DocumentRef<T>) => void,
84
+ ) => Unsubscribe;
85
+
86
+ readonly getRecordSnapshot: <R extends Model>(
87
+ recordRef: RecordRef<R>,
88
+ ) => Promise<ModelData<R>>;
89
+
90
+ readonly onCollectionItemsAdded: <M extends Model>(
91
+ collection: RecordCollectionRef<M>,
92
+ callback: RecordCollectionChangeCallback<M>,
93
+ ) => Unsubscribe;
94
+
95
+ readonly onCollectionItemsChanged: <M extends Model>(
96
+ collection: RecordCollectionRef<M>,
97
+ callback: RecordCollectionChangeCallback<M>,
98
+ ) => Unsubscribe;
99
+
100
+ readonly onCollectionItemsDeleted: <M extends Model>(
101
+ collection: RecordCollectionRef<M>,
102
+ callback: RecordCollectionChangeCallback<M>,
103
+ ) => Unsubscribe;
104
+
105
+ readonly setRecord: <R extends Model>(
106
+ recordRef: RecordRef<R>,
107
+ state: ModelData<R>,
108
+ ) => Promise<void>;
109
+
110
+ readonly updateRecord: <R extends Model>(
111
+ recordRef: RecordRef<R>,
112
+ partialState: Partial<ModelData<R>>,
113
+ ) => Promise<void>;
114
+
115
+ readonly onRecordChanged: <M extends Model>(
116
+ record: RecordRef<M>,
117
+ callback: RecordChangeCallback<M>,
118
+ ) => Unsubscribe;
119
+
120
+ readonly onRecordDeleted: <M extends Model>(
121
+ record: RecordRef<M>,
122
+ callback: RecordDeleteCallback<M>,
123
+ ) => Unsubscribe;
124
+
125
+ readonly deleteRecord: <M extends Model>(
126
+ record: RecordRef<M>,
127
+ ) => Promise<void>;
128
+
129
+ // Status methods
130
+ readonly getDocumentStatus: <T extends DocumentSchema>(
131
+ docRef: DocumentRef<T>,
132
+ ) => ReturnType<DocumentService["getDocumentStatus"]>;
133
+
134
+ readonly onStatusChange: <T extends DocumentSchema>(
135
+ docRef: DocumentRef<T>,
136
+ callback: Parameters<DocumentService["onStatusChange"]>[1],
137
+ ) => Unsubscribe;
138
+
139
+ readonly waitForMetadataLoad: <T extends DocumentSchema>(
140
+ docRef: DocumentRef<T>,
141
+ ) => Promise<void>;
142
+
143
+ readonly waitForDataLoad: <T extends DocumentSchema>(
144
+ docRef: DocumentRef<T>,
145
+ ) => Promise<void>;
146
+ }
147
+
148
+ export class StateModuleImpl implements StateModule {
149
+ constructor(
150
+ private readonly documentService: DocumentService,
151
+ ) {}
152
+
153
+ createDocRef<const T extends DocumentSchema>(
154
+ id: DocumentId,
155
+ schema: T,
156
+ ): DocumentRef<T> {
157
+ return this.documentService.createDocRef(id, schema);
158
+ }
159
+
160
+ createRecordRef<const M extends Model>(
161
+ docRef: DocumentRef,
162
+ id: RecordId,
163
+ model: M,
164
+ ): RecordRef<M> {
165
+ return this.documentService.getCreateRecordRef(docRef, id, model);
166
+ }
167
+
168
+ async createDocument<T extends DocumentSchema>(
169
+ metadata: DocumentMetadata,
170
+ schema: T,
171
+ ): Promise<DocumentRef<T>> {
172
+ return this.documentService.createDocument(metadata, schema);
173
+ }
174
+
175
+ async getDocumentSnapshot<T extends DocumentSchema>(
176
+ docRef: DocumentRef<T>,
177
+ ): Promise<DocumentState<T>> {
178
+ return this.documentService.getDocumentSnapshot(docRef);
179
+ }
180
+
181
+ onMetadataChange<T extends DocumentSchema>(
182
+ docRef: DocumentRef<T>,
183
+ cb: (doc: DocumentRef<T>, metadata: DocumentMetadata) => void,
184
+ ): Unsubscribe {
185
+ return this.documentService.onMetadataChange(docRef, cb);
186
+ }
187
+
188
+ onStateChange<T extends DocumentSchema>(
189
+ docRef: DocumentRef<T>,
190
+ cb: (docRef: DocumentRef<T>) => void,
191
+ ): Unsubscribe {
192
+ return this.documentService.onStateChange(docRef, cb);
193
+ }
194
+
195
+ async getRecordSnapshot<R extends Model>(
196
+ recordRef: RecordRef<R>,
197
+ ): Promise<ModelData<R>> {
198
+ return this.documentService.getRecordSnapshot(recordRef);
199
+ }
200
+
201
+ async setRecord<R extends Model>(
202
+ recordRef: RecordRef<R>,
203
+ state: ModelData<R>,
204
+ ): Promise<void> {
205
+ return this.documentService.setRecord(recordRef, state);
206
+ }
207
+
208
+ async updateRecord<R extends Model>(
209
+ recordRef: RecordRef<R>,
210
+ partialState: Partial<ModelData<R>>,
211
+ ): Promise<void> {
212
+ return this.documentService.updateRecord(recordRef, partialState);
213
+ }
214
+
215
+ // Collection methods
216
+ getCreateRecordCollectionRef<M extends Model>(
217
+ docRef: DocumentRef,
218
+ model: M,
219
+ ): RecordCollectionRef<M> {
220
+ return this.documentService.getCreateRecordCollectionRef(docRef, model);
221
+ }
222
+
223
+ // FIXME: confusing vs createRecordRef
224
+ getRecord<M extends Model>(
225
+ collection: RecordCollectionRef<M>,
226
+ id: RecordId,
227
+ ): RecordRef<M> | undefined {
228
+ return this.documentService.getRecord(collection, id);
229
+ }
230
+
231
+ hasRecord<M extends Model>(
232
+ collection: RecordCollectionRef<M>,
233
+ id: RecordId,
234
+ ): boolean {
235
+ return this.documentService.hasRecord(collection, id);
236
+ }
237
+
238
+ async setCollectionRecord<M extends Model>(
239
+ collection: RecordCollectionRef<M>,
240
+ id: RecordId,
241
+ state: ModelData<M>,
242
+ ): Promise<void> {
243
+ return this.documentService.setCollectionRecord(collection, id, state);
244
+ }
245
+
246
+ getCollectionSize<M extends Model>(
247
+ collection: RecordCollectionRef<M>,
248
+ ): number {
249
+ return this.documentService.getCollectionSize(collection);
250
+ }
251
+
252
+ getCollectionRecords<M extends Model>(
253
+ collection: RecordCollectionRef<M>,
254
+ ): RecordRef<M>[] {
255
+ return this.documentService.getCollectionRecords(collection);
256
+ }
257
+
258
+ onRecordChanged<M extends Model>(
259
+ record: RecordRef<M>,
260
+ callback: RecordChangeCallback<M>,
261
+ ): Unsubscribe {
262
+ return this.documentService.onRecordChanged(record, callback);
263
+ }
264
+
265
+ onRecordDeleted<M extends Model>(
266
+ record: RecordRef<M>,
267
+ callback: RecordDeleteCallback<M>,
268
+ ): Unsubscribe {
269
+ return this.documentService.onRecordDeleted(record, callback);
270
+ }
271
+
272
+ onCollectionItemsAdded<M extends Model>(
273
+ collection: RecordCollectionRef<M>,
274
+ callback: RecordCollectionChangeCallback<M>,
275
+ ): Unsubscribe {
276
+ return this.documentService.onCollectionItemsAdded(collection, callback);
277
+ }
278
+
279
+ onCollectionItemsChanged<M extends Model>(
280
+ collection: RecordCollectionRef<M>,
281
+ callback: RecordCollectionChangeCallback<M>,
282
+ ): Unsubscribe {
283
+ return this.documentService.onCollectionItemsChanged(collection, callback);
284
+ }
285
+
286
+ onCollectionItemsDeleted<M extends Model>(
287
+ collection: RecordCollectionRef<M>,
288
+ callback: RecordCollectionChangeCallback<M>,
289
+ ): Unsubscribe {
290
+ return this.documentService.onCollectionItemsDeleted(collection, callback);
291
+ }
292
+
293
+ // Status methods implementation
294
+ getDocumentStatus<T extends DocumentSchema>(
295
+ docRef: DocumentRef<T>,
296
+ ): ReturnType<DocumentService["getDocumentStatus"]> {
297
+ return this.documentService.getDocumentStatus(docRef);
298
+ }
299
+
300
+ onStatusChange<T extends DocumentSchema>(
301
+ docRef: DocumentRef<T>,
302
+ callback: Parameters<DocumentService["onStatusChange"]>[1],
303
+ ): Unsubscribe {
304
+ return this.documentService.onStatusChange(docRef, callback);
305
+ }
306
+
307
+ async waitForMetadataLoad<T extends DocumentSchema>(
308
+ docRef: DocumentRef<T>,
309
+ ): Promise<void> {
310
+ return this.documentService.waitForMetadataLoad(docRef);
311
+ }
312
+
313
+ async waitForDataLoad<T extends DocumentSchema>(
314
+ docRef: DocumentRef<T>,
315
+ ): Promise<void> {
316
+ return this.documentService.waitForDataLoad(docRef);
317
+ }
318
+
319
+ async deleteRecord<M extends Model>(
320
+ record: RecordRef<M>,
321
+ ): Promise<void> {
322
+ return this.documentService.deleteRecord(record);
323
+ }
324
+ }
325
+
326
+ export function getStateModule(app: PackAppInternal): StateModule {
327
+ assertIsAppInternal(app);
328
+ return app.getModule(STATE_MODULE_KEY);
329
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "@palantir/pack.monorepo.tsconfig/base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./build/esm",
5
+ "rootDir": "./src",
6
+ "declarationDir": "./build/types",
7
+ "tsBuildInfoFile": "./build/tsconfig.tsbuildinfo"
8
+ },
9
+ "include": [
10
+ "src/**/*"
11
+ ],
12
+ "exclude": [
13
+ "build",
14
+ "dist",
15
+ "node_modules",
16
+ "test-output",
17
+ "**/__tests__/**/__snapshots__",
18
+ "**/__tests__/**/fixtures"
19
+ ],
20
+ "references": []
21
+ }
@@ -0,0 +1,26 @@
1
+ import { coverageConfigDefaults, defaultExclude, defineProject } from "vitest/config";
2
+
3
+ export default defineProject({
4
+ test: {
5
+ exclude: [...defaultExclude, "**/build/**", "**/test-output/**"],
6
+ coverage: {
7
+ provider: "v8",
8
+ all: true,
9
+ enabled: true,
10
+ pool: "forks",
11
+ include: ["src/**/*.{ts,tsx}"],
12
+ exclude: [
13
+ ...coverageConfigDefaults.exclude,
14
+ "**/*.test.{ts,tsx}",
15
+ "**/__tests__",
16
+ "build",
17
+ "coverage",
18
+ "dist",
19
+ "node_modules",
20
+ "src/index.ts",
21
+ "test-output",
22
+ "vitest.config.*",
23
+ ],
24
+ },
25
+ },
26
+ });