@palantir/pack.state.core 0.1.0-beta.2 → 0.1.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.
- package/.turbo/turbo-lint.log +2 -2
- package/.turbo/turbo-transpileBrowser.log +1 -1
- package/.turbo/turbo-transpileCjs.log +1 -1
- package/.turbo/turbo-transpileEsm.log +1 -1
- package/.turbo/turbo-transpileTypes.log +1 -1
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +33 -0
- package/build/browser/index.js +73 -0
- package/build/browser/index.js.map +1 -1
- package/build/cjs/index.cjs +73 -0
- package/build/cjs/index.cjs.map +1 -1
- package/build/cjs/index.d.cts +106 -1
- package/build/esm/index.js +73 -0
- package/build/esm/index.js.map +1 -1
- package/build/types/__tests__/Transaction.test.d.ts +1 -0
- package/build/types/__tests__/Transaction.test.d.ts.map +1 -0
- package/build/types/__tests__/testUtils.d.ts.map +1 -1
- package/build/types/service/BaseYjsDocumentService.d.ts +11 -1
- package/build/types/service/BaseYjsDocumentService.d.ts.map +1 -1
- package/build/types/service/InMemoryDocumentService.d.ts.map +1 -1
- package/build/types/types/DocumentRefImpl.d.ts +20 -0
- package/build/types/types/DocumentRefImpl.d.ts.map +1 -1
- package/build/types/types/DocumentService.d.ts +18 -1
- package/build/types/types/DocumentService.d.ts.map +1 -1
- package/build/types/types/RecordCollectionRefImpl.d.ts +23 -0
- package/build/types/types/RecordCollectionRefImpl.d.ts.map +1 -1
- package/build/types/types/RecordRefImpl.d.ts +25 -0
- package/build/types/types/RecordRefImpl.d.ts.map +1 -1
- package/build/types/types/StateModule.d.ts +21 -1
- package/build/types/types/StateModule.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/__tests__/Transaction.test.ts +321 -0
- package/src/__tests__/testUtils.ts +1 -2
- package/src/service/BaseYjsDocumentService.ts +41 -0
- package/src/service/InMemoryDocumentService.ts +58 -1
- package/src/types/DocumentRefImpl.ts +58 -0
- package/src/types/DocumentService.ts +43 -0
- package/src/types/RecordCollectionRefImpl.ts +23 -0
- package/src/types/RecordRefImpl.ts +25 -0
- package/src/types/StateModule.ts +78 -0
|
@@ -19,14 +19,17 @@
|
|
|
19
19
|
import type { Logger } from "@osdk/api";
|
|
20
20
|
import type { PackAppInternal, Unsubscribe } from "@palantir/pack.core";
|
|
21
21
|
import {
|
|
22
|
+
type ActivityEvent,
|
|
22
23
|
type DocumentId,
|
|
23
24
|
type DocumentMetadata,
|
|
24
25
|
type DocumentRef,
|
|
25
26
|
type DocumentSchema,
|
|
26
27
|
type DocumentState,
|
|
28
|
+
type EditDescription,
|
|
27
29
|
getMetadata,
|
|
28
30
|
type Model,
|
|
29
31
|
type ModelData,
|
|
32
|
+
type PresenceEvent,
|
|
30
33
|
type RecordCollectionRef,
|
|
31
34
|
type RecordId,
|
|
32
35
|
type RecordRef,
|
|
@@ -124,6 +127,14 @@ export abstract class BaseYjsDocumentService<TDoc extends InternalYjsDoc = Inter
|
|
|
124
127
|
metadata: DocumentMetadata,
|
|
125
128
|
schema: T,
|
|
126
129
|
) => Promise<DocumentRef<T>>;
|
|
130
|
+
abstract readonly searchDocuments: <T extends DocumentSchema>(
|
|
131
|
+
documentTypeName: string,
|
|
132
|
+
schema: T,
|
|
133
|
+
options?: {
|
|
134
|
+
documentName?: string;
|
|
135
|
+
limit?: number;
|
|
136
|
+
},
|
|
137
|
+
) => Promise<ReadonlyArray<DocumentMetadata & { readonly id: DocumentId }>>;
|
|
127
138
|
|
|
128
139
|
readonly createDocRef = <const T extends DocumentSchema>(
|
|
129
140
|
id: DocumentId,
|
|
@@ -486,6 +497,20 @@ export abstract class BaseYjsDocumentService<TDoc extends InternalYjsDoc = Inter
|
|
|
486
497
|
return Promise.resolve();
|
|
487
498
|
};
|
|
488
499
|
|
|
500
|
+
readonly withTransaction = (
|
|
501
|
+
docRef: DocumentRef,
|
|
502
|
+
fn: () => void,
|
|
503
|
+
description?: EditDescription,
|
|
504
|
+
): void => {
|
|
505
|
+
const internalDoc = this.documents.get(docRef.id);
|
|
506
|
+
invariant(
|
|
507
|
+
internalDoc != null,
|
|
508
|
+
`Cannot start transaction as document not found: ${docRef.id}`,
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
internalDoc.yDoc.transact(fn, description);
|
|
512
|
+
};
|
|
513
|
+
|
|
489
514
|
onMetadataChange<T extends DocumentSchema>(
|
|
490
515
|
docRef: DocumentRef<T>,
|
|
491
516
|
callback: DocumentMetadataChangeCallback<T>,
|
|
@@ -520,6 +545,22 @@ export abstract class BaseYjsDocumentService<TDoc extends InternalYjsDoc = Inter
|
|
|
520
545
|
};
|
|
521
546
|
}
|
|
522
547
|
|
|
548
|
+
abstract onActivity<T extends DocumentSchema>(
|
|
549
|
+
docRef: DocumentRef<T>,
|
|
550
|
+
callback: (docRef: DocumentRef<T>, event: ActivityEvent) => void,
|
|
551
|
+
): Unsubscribe;
|
|
552
|
+
|
|
553
|
+
abstract onPresence<T extends DocumentSchema>(
|
|
554
|
+
docRef: DocumentRef<T>,
|
|
555
|
+
callback: (docRef: DocumentRef<T>, event: PresenceEvent) => void,
|
|
556
|
+
): Unsubscribe;
|
|
557
|
+
|
|
558
|
+
abstract updateCustomPresence<M extends Model>(
|
|
559
|
+
docRef: DocumentRef,
|
|
560
|
+
model: M,
|
|
561
|
+
eventData: ModelData<M>,
|
|
562
|
+
): void;
|
|
563
|
+
|
|
523
564
|
readonly onStateChange = <T extends DocumentSchema>(
|
|
524
565
|
docRef: DocumentRef<T>,
|
|
525
566
|
callback: DocumentStateChangeCallback<T>,
|
|
@@ -14,13 +14,18 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import type { ModuleConfigTuple, PackAppInternal } from "@palantir/pack.core";
|
|
17
|
+
import type { ModuleConfigTuple, PackAppInternal, Unsubscribe } from "@palantir/pack.core";
|
|
18
18
|
import { generateId } from "@palantir/pack.core";
|
|
19
19
|
import type {
|
|
20
|
+
ActivityEvent,
|
|
20
21
|
DocumentId,
|
|
21
22
|
DocumentMetadata,
|
|
22
23
|
DocumentRef,
|
|
23
24
|
DocumentSchema,
|
|
25
|
+
Model,
|
|
26
|
+
ModelData,
|
|
27
|
+
PresenceEvent,
|
|
28
|
+
PresenceSubscriptionOptions,
|
|
24
29
|
} from "@palantir/pack.document-schema.model-types";
|
|
25
30
|
import type * as Y from "yjs";
|
|
26
31
|
import { createDocumentServiceConfig } from "../DocumentServiceModule.js";
|
|
@@ -99,6 +104,36 @@ class InMemoryDocumentService extends BaseYjsDocumentService {
|
|
|
99
104
|
return Promise.resolve(docRef);
|
|
100
105
|
};
|
|
101
106
|
|
|
107
|
+
readonly searchDocuments = <T extends DocumentSchema>(
|
|
108
|
+
documentTypeName: string,
|
|
109
|
+
schema: T,
|
|
110
|
+
options?: {
|
|
111
|
+
documentName?: string;
|
|
112
|
+
limit?: number;
|
|
113
|
+
},
|
|
114
|
+
): Promise<ReadonlyArray<DocumentMetadata & { readonly id: DocumentId }>> => {
|
|
115
|
+
const results: Array<DocumentMetadata & { readonly id: DocumentId }> = [];
|
|
116
|
+
const { documentName, limit } = options ?? {};
|
|
117
|
+
|
|
118
|
+
for (const [docId, internalDoc] of this.documents.entries()) {
|
|
119
|
+
if (internalDoc.metadata?.documentTypeName === documentTypeName) {
|
|
120
|
+
if (documentName && !internalDoc.metadata.name.includes(documentName)) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
results.push({
|
|
124
|
+
...internalDoc.metadata,
|
|
125
|
+
id: docId as DocumentId,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
if (limit && results.length >= limit) {
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return Promise.resolve(results);
|
|
135
|
+
};
|
|
136
|
+
|
|
102
137
|
// Lifecycle method implementations
|
|
103
138
|
protected onMetadataSubscriptionOpened(
|
|
104
139
|
internalDoc: InternalYjsDoc,
|
|
@@ -155,6 +190,28 @@ class InMemoryDocumentService extends BaseYjsDocumentService {
|
|
|
155
190
|
): void {
|
|
156
191
|
// No cleanup needed for in-memory service
|
|
157
192
|
}
|
|
193
|
+
|
|
194
|
+
onActivity<T extends DocumentSchema>(
|
|
195
|
+
_docRef: DocumentRef<T>,
|
|
196
|
+
_callback: (docRef: DocumentRef<T>, event: ActivityEvent) => void,
|
|
197
|
+
): Unsubscribe {
|
|
198
|
+
return () => {};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
onPresence<T extends DocumentSchema>(
|
|
202
|
+
_docRef: DocumentRef<T>,
|
|
203
|
+
_callback: (docRef: DocumentRef<T>, event: PresenceEvent) => void,
|
|
204
|
+
_options?: PresenceSubscriptionOptions,
|
|
205
|
+
): Unsubscribe {
|
|
206
|
+
return () => {};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
updateCustomPresence<M extends Model>(
|
|
210
|
+
_docRef: DocumentRef,
|
|
211
|
+
_model: M,
|
|
212
|
+
_eventData: ModelData<M>,
|
|
213
|
+
): void {
|
|
214
|
+
}
|
|
158
215
|
}
|
|
159
216
|
|
|
160
217
|
function generateDocumentId(): DocumentId {
|
|
@@ -16,12 +16,17 @@
|
|
|
16
16
|
|
|
17
17
|
import type { PackAppInternal } from "@palantir/pack.core";
|
|
18
18
|
import type {
|
|
19
|
+
ActivityEvent,
|
|
19
20
|
DocumentId,
|
|
20
21
|
DocumentMetadata,
|
|
21
22
|
DocumentRef,
|
|
22
23
|
DocumentSchema,
|
|
23
24
|
DocumentState,
|
|
25
|
+
EditDescription,
|
|
24
26
|
Model,
|
|
27
|
+
ModelData,
|
|
28
|
+
PresenceEvent,
|
|
29
|
+
PresenceSubscriptionOptions,
|
|
25
30
|
RecordCollectionRef,
|
|
26
31
|
Unsubscribe,
|
|
27
32
|
} from "@palantir/pack.document-schema.model-types";
|
|
@@ -39,8 +44,14 @@ const INVALID_DOC_REF: DocumentRef = Object.freeze(
|
|
|
39
44
|
getRecords: () => {
|
|
40
45
|
throw new Error("Invalid document reference");
|
|
41
46
|
},
|
|
47
|
+
onActivity: () => () => {},
|
|
42
48
|
onMetadataChange: () => () => {},
|
|
49
|
+
onPresence: () => () => {},
|
|
43
50
|
onStateChange: () => () => {},
|
|
51
|
+
updateCustomPresence: () => {},
|
|
52
|
+
withTransaction: () => {
|
|
53
|
+
throw new Error("Invalid document reference");
|
|
54
|
+
},
|
|
44
55
|
} as const,
|
|
45
56
|
);
|
|
46
57
|
|
|
@@ -52,10 +63,30 @@ export const createDocRef = <const D extends DocumentSchema>(
|
|
|
52
63
|
return new DocumentRefImpl(app, id, schema);
|
|
53
64
|
};
|
|
54
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Get an invalid document reference. This is a stable reference that can be
|
|
68
|
+
* used to represent a non-existent or invalid document.
|
|
69
|
+
*
|
|
70
|
+
* Not to be confused with a valid reference to a non-existent document, an
|
|
71
|
+
* invalid reference is one that is not properly initialized. For example, code
|
|
72
|
+
* that initializes with an undefined or empty documentId might produce an
|
|
73
|
+
* invalid document reference rather than propagate nullish types.
|
|
74
|
+
*
|
|
75
|
+
* Most operations on an invalid reference are no-ops. For the rest, it is
|
|
76
|
+
* recommended to check for validity using {@link isValidDocRef} before
|
|
77
|
+
* performing operations.
|
|
78
|
+
*/
|
|
55
79
|
export function invalidDocRef<D extends DocumentSchema = DocumentSchema>(): DocumentRef<D> {
|
|
56
80
|
return INVALID_DOC_REF as DocumentRef<D>;
|
|
57
81
|
}
|
|
58
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Check if a document reference is an invalid reference.
|
|
85
|
+
* Not to be confused with a valid reference to a non-existent document, an invalid reference is one that is not properly initialized.
|
|
86
|
+
* For example, code that initializes with an undefined or empty documentId might produce an invalid document reference rather than
|
|
87
|
+
* propagate nullish types, as most operations on an invalid reference are no-ops. For the rest, it is recommended to check for
|
|
88
|
+
* validity using this function before performing operations.
|
|
89
|
+
*/
|
|
59
90
|
export function isValidDocRef<D extends DocumentSchema = DocumentSchema>(
|
|
60
91
|
docRef: DocumentRef<D>,
|
|
61
92
|
): docRef is DocumentRef<D> {
|
|
@@ -84,15 +115,42 @@ class DocumentRefImpl<T extends DocumentSchema> implements DocumentRef<T> {
|
|
|
84
115
|
return this.#stateModule.getCreateRecordCollectionRef(this, model);
|
|
85
116
|
}
|
|
86
117
|
|
|
118
|
+
onActivity(
|
|
119
|
+
callback: (docRef: DocumentRef<T>, event: ActivityEvent) => void,
|
|
120
|
+
): Unsubscribe {
|
|
121
|
+
return this.#stateModule.onActivity(this, callback);
|
|
122
|
+
}
|
|
123
|
+
|
|
87
124
|
onMetadataChange(
|
|
88
125
|
cb: (docRef: DocumentRef<T>, metadata: DocumentMetadata) => void,
|
|
89
126
|
): Unsubscribe {
|
|
90
127
|
return this.#stateModule.onMetadataChange(this, cb);
|
|
91
128
|
}
|
|
92
129
|
|
|
130
|
+
onPresence(
|
|
131
|
+
callback: (docRef: DocumentRef<T>, event: PresenceEvent) => void,
|
|
132
|
+
options?: PresenceSubscriptionOptions,
|
|
133
|
+
): Unsubscribe {
|
|
134
|
+
return this.#stateModule.onPresence(this, callback, options);
|
|
135
|
+
}
|
|
136
|
+
|
|
93
137
|
onStateChange(
|
|
94
138
|
callback: (docRef: DocumentRef<T>) => void,
|
|
95
139
|
): Unsubscribe {
|
|
96
140
|
return this.#stateModule.onStateChange(this, callback);
|
|
97
141
|
}
|
|
142
|
+
|
|
143
|
+
updateCustomPresence<M extends Model = Model>(
|
|
144
|
+
model: M,
|
|
145
|
+
eventData: ModelData<M>,
|
|
146
|
+
): void {
|
|
147
|
+
this.#stateModule.updateCustomPresence(this, model, eventData);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
withTransaction(
|
|
151
|
+
fn: () => void,
|
|
152
|
+
description?: EditDescription,
|
|
153
|
+
): void {
|
|
154
|
+
this.#stateModule.withTransaction(this, fn, description);
|
|
155
|
+
}
|
|
98
156
|
}
|
|
@@ -16,13 +16,17 @@
|
|
|
16
16
|
|
|
17
17
|
import type { Unsubscribe } from "@palantir/pack.core";
|
|
18
18
|
import type {
|
|
19
|
+
ActivityEvent,
|
|
19
20
|
DocumentId,
|
|
20
21
|
DocumentMetadata,
|
|
21
22
|
DocumentRef,
|
|
22
23
|
DocumentSchema,
|
|
23
24
|
DocumentState,
|
|
25
|
+
EditDescription,
|
|
24
26
|
Model,
|
|
25
27
|
ModelData,
|
|
28
|
+
PresenceEvent,
|
|
29
|
+
PresenceSubscriptionOptions,
|
|
26
30
|
RecordCollectionRef,
|
|
27
31
|
RecordId,
|
|
28
32
|
RecordRef,
|
|
@@ -83,6 +87,13 @@ export type RecordDeleteCallback<M extends Model = Model> = (
|
|
|
83
87
|
record: RecordRef<M>,
|
|
84
88
|
) => void;
|
|
85
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Base interface for specific document service implementations.
|
|
92
|
+
* The DocumentService is responsible for persisting document state,
|
|
93
|
+
* metadata, and providing methods to subscribe and interact with documents.
|
|
94
|
+
*
|
|
95
|
+
* The main implementation communicates with the Foundry platform (see @palantir/pack.state.foundry).
|
|
96
|
+
*/
|
|
86
97
|
export interface DocumentService {
|
|
87
98
|
readonly hasMetadataSubscriptions: boolean;
|
|
88
99
|
readonly hasStateSubscriptions: boolean;
|
|
@@ -92,6 +103,15 @@ export interface DocumentService {
|
|
|
92
103
|
schema: T,
|
|
93
104
|
) => Promise<DocumentRef<T>>;
|
|
94
105
|
|
|
106
|
+
readonly searchDocuments: <T extends DocumentSchema>(
|
|
107
|
+
documentTypeName: string,
|
|
108
|
+
schema: T,
|
|
109
|
+
options?: {
|
|
110
|
+
documentName?: string;
|
|
111
|
+
limit?: number;
|
|
112
|
+
},
|
|
113
|
+
) => Promise<ReadonlyArray<DocumentMetadata & { readonly id: DocumentId }>>;
|
|
114
|
+
|
|
95
115
|
readonly createDocRef: <const T extends DocumentSchema>(
|
|
96
116
|
id: DocumentId,
|
|
97
117
|
schema: T,
|
|
@@ -126,6 +146,12 @@ export interface DocumentService {
|
|
|
126
146
|
partialState: Partial<ModelData<R>>,
|
|
127
147
|
) => Promise<void>;
|
|
128
148
|
|
|
149
|
+
readonly withTransaction: (
|
|
150
|
+
docRef: DocumentRef,
|
|
151
|
+
fn: () => void,
|
|
152
|
+
description?: EditDescription,
|
|
153
|
+
) => void;
|
|
154
|
+
|
|
129
155
|
// Collection methods
|
|
130
156
|
readonly getRecord: <M extends Model>(
|
|
131
157
|
collection: RecordCollectionRef<M>,
|
|
@@ -170,16 +196,33 @@ export interface DocumentService {
|
|
|
170
196
|
callback: RecordCollectionChangeCallback<M>,
|
|
171
197
|
) => Unsubscribe;
|
|
172
198
|
|
|
199
|
+
readonly onActivity: <T extends DocumentSchema>(
|
|
200
|
+
docRef: DocumentRef<T>,
|
|
201
|
+
callback: (docRef: DocumentRef<T>, event: ActivityEvent) => void,
|
|
202
|
+
) => Unsubscribe;
|
|
203
|
+
|
|
173
204
|
readonly onMetadataChange: <T extends DocumentSchema>(
|
|
174
205
|
docRef: DocumentRef<T>,
|
|
175
206
|
callback: DocumentMetadataChangeCallback<T>,
|
|
176
207
|
) => Unsubscribe;
|
|
177
208
|
|
|
209
|
+
readonly onPresence: <T extends DocumentSchema>(
|
|
210
|
+
docRef: DocumentRef<T>,
|
|
211
|
+
callback: (docRef: DocumentRef<T>, event: PresenceEvent) => void,
|
|
212
|
+
options?: PresenceSubscriptionOptions,
|
|
213
|
+
) => Unsubscribe;
|
|
214
|
+
|
|
178
215
|
readonly onStateChange: <T extends DocumentSchema>(
|
|
179
216
|
docRef: DocumentRef<T>,
|
|
180
217
|
callback: DocumentStateChangeCallback<T>,
|
|
181
218
|
) => Unsubscribe;
|
|
182
219
|
|
|
220
|
+
readonly updateCustomPresence: <M extends Model>(
|
|
221
|
+
docRef: DocumentRef,
|
|
222
|
+
model: M,
|
|
223
|
+
eventData: ModelData<M>,
|
|
224
|
+
) => void;
|
|
225
|
+
|
|
183
226
|
readonly onRecordChanged: <M extends Model>(
|
|
184
227
|
record: RecordRef<M>,
|
|
185
228
|
callback: RecordChangeCallback<M>,
|
|
@@ -54,10 +54,33 @@ export const createRecordCollectionRef = <const M extends Model>(
|
|
|
54
54
|
return new RecordCollectionRefImpl(documentService, docRef, model);
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Get an invalid record collection reference. This is a stable reference that
|
|
59
|
+
* can be used to represent an invalid record collection.
|
|
60
|
+
*
|
|
61
|
+
* Not to be confused with a valid reference to a non-existent record
|
|
62
|
+
* collection, an invalid reference is one that is not properly initialized. For
|
|
63
|
+
* example, code that initializes with an undefined or empty model might produce
|
|
64
|
+
* an invalid record collection reference rather than propagate nullish types.
|
|
65
|
+
*
|
|
66
|
+
* Most operations on an invalid reference are no-ops. For the rest, it is
|
|
67
|
+
* recommended to check for validity using {@link isValidRecordCollectionRef}
|
|
68
|
+
* before performing operations.
|
|
69
|
+
*/
|
|
57
70
|
export function invalidRecordCollectionRef<M extends Model = Model>(): RecordCollectionRef<M> {
|
|
58
71
|
return INVALID_RECORD_COLLECTION_REF as RecordCollectionRef<M>;
|
|
59
72
|
}
|
|
60
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Check if a record collection reference is a valid reference.
|
|
76
|
+
*
|
|
77
|
+
* Not to be confused with a valid reference to a non-existent record
|
|
78
|
+
* collection, an invalid reference is one that is not properly initialized.
|
|
79
|
+
*
|
|
80
|
+
* Most operations on an invalid reference are no-ops. For the rest, it is
|
|
81
|
+
* recommended to check for validity using this function before performing
|
|
82
|
+
* operations.
|
|
83
|
+
*/
|
|
61
84
|
export function isValidRecordCollectionRef<M extends Model = Model>(
|
|
62
85
|
collectionRef: RecordCollectionRef<M>,
|
|
63
86
|
): collectionRef is RecordCollectionRef<M> {
|
|
@@ -49,10 +49,35 @@ export const createRecordRef = <const M extends Model>(
|
|
|
49
49
|
return new RecordRefImpl(documentService, docRef, id, model);
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Get an invalid record reference. This is a stable reference that can be used
|
|
54
|
+
* to represent an invalid record.
|
|
55
|
+
*
|
|
56
|
+
* Not to be confused with a valid reference to a non-existent record, an
|
|
57
|
+
* invalid reference is one that is not properly initialized. For example, code
|
|
58
|
+
* that initializes with an undefined or empty recordId might produce an
|
|
59
|
+
* invalid record reference rather than propagate nullish types.
|
|
60
|
+
*
|
|
61
|
+
* Most operations on an invalid reference are no-ops. For the rest, it is
|
|
62
|
+
* recommended to check for validity using {@link isValidRecordRef} before
|
|
63
|
+
* performing operations.
|
|
64
|
+
*/
|
|
52
65
|
export function invalidRecordRef<M extends Model = Model>(): RecordRef<M> {
|
|
53
66
|
return INVALID_RECORD_REF as RecordRef<M>;
|
|
54
67
|
}
|
|
55
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Check if a record reference is a valid reference.
|
|
71
|
+
*
|
|
72
|
+
* Not to be confused with a valid reference to a non-existent record, an
|
|
73
|
+
* invalid reference is one that is not properly initialized.
|
|
74
|
+
*
|
|
75
|
+
* For example, code that initializes with an undefined or empty recordId might
|
|
76
|
+
* produce an invalid record reference rather than propagate nullish types, as
|
|
77
|
+
* most operations on an invalid reference are no-ops. For the rest, it is
|
|
78
|
+
* recommended to check for validity using this function before performing
|
|
79
|
+
* operations.
|
|
80
|
+
*/
|
|
56
81
|
export function isValidRecordRef<M extends Model = Model>(
|
|
57
82
|
recordRef: RecordRef<M>,
|
|
58
83
|
): recordRef is RecordRef<M> {
|
package/src/types/StateModule.ts
CHANGED
|
@@ -21,13 +21,17 @@ import {
|
|
|
21
21
|
type Unsubscribe,
|
|
22
22
|
} from "@palantir/pack.core";
|
|
23
23
|
import type {
|
|
24
|
+
ActivityEvent,
|
|
24
25
|
DocumentId,
|
|
25
26
|
DocumentMetadata,
|
|
26
27
|
DocumentRef,
|
|
27
28
|
DocumentSchema,
|
|
28
29
|
DocumentState,
|
|
30
|
+
EditDescription,
|
|
29
31
|
Model,
|
|
30
32
|
ModelData,
|
|
33
|
+
PresenceEvent,
|
|
34
|
+
PresenceSubscriptionOptions,
|
|
31
35
|
RecordCollectionRef,
|
|
32
36
|
RecordId,
|
|
33
37
|
RecordRef,
|
|
@@ -69,20 +73,46 @@ export interface StateModule {
|
|
|
69
73
|
schema: T,
|
|
70
74
|
) => Promise<DocumentRef<T>>;
|
|
71
75
|
|
|
76
|
+
readonly searchDocuments: <T extends DocumentSchema>(
|
|
77
|
+
documentTypeName: string,
|
|
78
|
+
schema: T,
|
|
79
|
+
options?: {
|
|
80
|
+
documentName?: string;
|
|
81
|
+
limit?: number;
|
|
82
|
+
},
|
|
83
|
+
) => Promise<ReadonlyArray<DocumentMetadata & { readonly id: DocumentId }>>;
|
|
84
|
+
|
|
72
85
|
readonly getDocumentSnapshot: <T extends DocumentSchema>(
|
|
73
86
|
docRef: DocumentRef<T>,
|
|
74
87
|
) => Promise<DocumentState<T>>;
|
|
75
88
|
|
|
89
|
+
readonly onActivity: <T extends DocumentSchema>(
|
|
90
|
+
docRef: DocumentRef<T>,
|
|
91
|
+
callback: (docRef: DocumentRef<T>, event: ActivityEvent) => void,
|
|
92
|
+
) => Unsubscribe;
|
|
93
|
+
|
|
76
94
|
readonly onMetadataChange: <T extends DocumentSchema>(
|
|
77
95
|
docRef: DocumentRef<T>,
|
|
78
96
|
cb: (docRef: DocumentRef<T>, metadata: DocumentMetadata) => void,
|
|
79
97
|
) => Unsubscribe;
|
|
80
98
|
|
|
99
|
+
readonly onPresence: <T extends DocumentSchema>(
|
|
100
|
+
docRef: DocumentRef<T>,
|
|
101
|
+
callback: (docRef: DocumentRef<T>, event: PresenceEvent) => void,
|
|
102
|
+
options?: PresenceSubscriptionOptions,
|
|
103
|
+
) => Unsubscribe;
|
|
104
|
+
|
|
81
105
|
readonly onStateChange: <T extends DocumentSchema>(
|
|
82
106
|
docRef: DocumentRef<T>,
|
|
83
107
|
cb: (docRef: DocumentRef<T>) => void,
|
|
84
108
|
) => Unsubscribe;
|
|
85
109
|
|
|
110
|
+
readonly updateCustomPresence: <M extends Model>(
|
|
111
|
+
docRef: DocumentRef,
|
|
112
|
+
model: M,
|
|
113
|
+
eventData: ModelData<M>,
|
|
114
|
+
) => void;
|
|
115
|
+
|
|
86
116
|
readonly getRecordSnapshot: <R extends Model>(
|
|
87
117
|
recordRef: RecordRef<R>,
|
|
88
118
|
) => Promise<ModelData<R>>;
|
|
@@ -112,6 +142,12 @@ export interface StateModule {
|
|
|
112
142
|
partialState: Partial<ModelData<R>>,
|
|
113
143
|
) => Promise<void>;
|
|
114
144
|
|
|
145
|
+
readonly withTransaction: (
|
|
146
|
+
docRef: DocumentRef,
|
|
147
|
+
fn: () => void,
|
|
148
|
+
description?: EditDescription,
|
|
149
|
+
) => void;
|
|
150
|
+
|
|
115
151
|
readonly onRecordChanged: <M extends Model>(
|
|
116
152
|
record: RecordRef<M>,
|
|
117
153
|
callback: RecordChangeCallback<M>,
|
|
@@ -172,12 +208,30 @@ export class StateModuleImpl implements StateModule {
|
|
|
172
208
|
return this.documentService.createDocument(metadata, schema);
|
|
173
209
|
}
|
|
174
210
|
|
|
211
|
+
async searchDocuments<T extends DocumentSchema>(
|
|
212
|
+
documentTypeName: string,
|
|
213
|
+
schema: T,
|
|
214
|
+
options?: {
|
|
215
|
+
documentName?: string;
|
|
216
|
+
limit?: number;
|
|
217
|
+
},
|
|
218
|
+
): Promise<ReadonlyArray<DocumentMetadata & { readonly id: DocumentId }>> {
|
|
219
|
+
return this.documentService.searchDocuments(documentTypeName, schema, options);
|
|
220
|
+
}
|
|
221
|
+
|
|
175
222
|
async getDocumentSnapshot<T extends DocumentSchema>(
|
|
176
223
|
docRef: DocumentRef<T>,
|
|
177
224
|
): Promise<DocumentState<T>> {
|
|
178
225
|
return this.documentService.getDocumentSnapshot(docRef);
|
|
179
226
|
}
|
|
180
227
|
|
|
228
|
+
onActivity<T extends DocumentSchema>(
|
|
229
|
+
docRef: DocumentRef<T>,
|
|
230
|
+
callback: (docRef: DocumentRef<T>, event: ActivityEvent) => void,
|
|
231
|
+
): Unsubscribe {
|
|
232
|
+
return this.documentService.onActivity(docRef, callback);
|
|
233
|
+
}
|
|
234
|
+
|
|
181
235
|
onMetadataChange<T extends DocumentSchema>(
|
|
182
236
|
docRef: DocumentRef<T>,
|
|
183
237
|
cb: (doc: DocumentRef<T>, metadata: DocumentMetadata) => void,
|
|
@@ -185,6 +239,14 @@ export class StateModuleImpl implements StateModule {
|
|
|
185
239
|
return this.documentService.onMetadataChange(docRef, cb);
|
|
186
240
|
}
|
|
187
241
|
|
|
242
|
+
onPresence<T extends DocumentSchema>(
|
|
243
|
+
docRef: DocumentRef<T>,
|
|
244
|
+
callback: (docRef: DocumentRef<T>, event: PresenceEvent) => void,
|
|
245
|
+
options?: PresenceSubscriptionOptions,
|
|
246
|
+
): Unsubscribe {
|
|
247
|
+
return this.documentService.onPresence(docRef, callback, options);
|
|
248
|
+
}
|
|
249
|
+
|
|
188
250
|
onStateChange<T extends DocumentSchema>(
|
|
189
251
|
docRef: DocumentRef<T>,
|
|
190
252
|
cb: (docRef: DocumentRef<T>) => void,
|
|
@@ -192,6 +254,14 @@ export class StateModuleImpl implements StateModule {
|
|
|
192
254
|
return this.documentService.onStateChange(docRef, cb);
|
|
193
255
|
}
|
|
194
256
|
|
|
257
|
+
updateCustomPresence<M extends Model>(
|
|
258
|
+
docRef: DocumentRef,
|
|
259
|
+
model: M,
|
|
260
|
+
eventData: ModelData<M>,
|
|
261
|
+
): void {
|
|
262
|
+
this.documentService.updateCustomPresence(docRef, model, eventData);
|
|
263
|
+
}
|
|
264
|
+
|
|
195
265
|
async getRecordSnapshot<R extends Model>(
|
|
196
266
|
recordRef: RecordRef<R>,
|
|
197
267
|
): Promise<ModelData<R>> {
|
|
@@ -212,6 +282,14 @@ export class StateModuleImpl implements StateModule {
|
|
|
212
282
|
return this.documentService.updateRecord(recordRef, partialState);
|
|
213
283
|
}
|
|
214
284
|
|
|
285
|
+
withTransaction(
|
|
286
|
+
docRef: DocumentRef,
|
|
287
|
+
fn: () => void,
|
|
288
|
+
description?: EditDescription,
|
|
289
|
+
): void {
|
|
290
|
+
this.documentService.withTransaction(docRef, fn, description);
|
|
291
|
+
}
|
|
292
|
+
|
|
215
293
|
// Collection methods
|
|
216
294
|
getCreateRecordCollectionRef<M extends Model>(
|
|
217
295
|
docRef: DocumentRef,
|