@palantir/pack.document-schema.model-types 0.2.0 → 0.2.2

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 (39) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/.turbo/turbo-transpileBrowser.log +1 -1
  3. package/.turbo/turbo-transpileCjs.log +1 -1
  4. package/.turbo/turbo-transpileEsm.log +1 -1
  5. package/.turbo/turbo-transpileTypes.log +1 -1
  6. package/.turbo/turbo-typecheck.log +1 -1
  7. package/CHANGELOG.md +12 -0
  8. package/build/browser/index.js +67 -5
  9. package/build/browser/index.js.map +1 -1
  10. package/build/cjs/index.cjs +69 -4
  11. package/build/cjs/index.cjs.map +1 -1
  12. package/build/cjs/index.d.cts +174 -13
  13. package/build/esm/index.js +67 -5
  14. package/build/esm/index.js.map +1 -1
  15. package/build/types/index.d.ts +4 -2
  16. package/build/types/index.d.ts.map +1 -1
  17. package/build/types/types/ActivityEvent.d.ts +1 -1
  18. package/build/types/types/ActivityEvent.d.ts.map +1 -1
  19. package/build/types/types/DocumentRef.d.ts +3 -6
  20. package/build/types/types/DocumentRef.d.ts.map +1 -1
  21. package/build/types/types/Metadata.d.ts +3 -1
  22. package/build/types/types/Metadata.d.ts.map +1 -1
  23. package/build/types/types/PresenceEvent.d.ts +3 -3
  24. package/build/types/types/PresenceEvent.d.ts.map +1 -1
  25. package/build/types/types/RecordRef.d.ts +26 -1
  26. package/build/types/types/RecordRef.d.ts.map +1 -1
  27. package/build/types/utils/ActivityEvents.d.ts +59 -0
  28. package/build/types/utils/ActivityEvents.d.ts.map +1 -0
  29. package/build/types/utils/PresenceEvents.d.ts +66 -0
  30. package/build/types/utils/PresenceEvents.d.ts.map +1 -0
  31. package/package.json +1 -1
  32. package/src/index.ts +4 -2
  33. package/src/types/ActivityEvent.ts +1 -1
  34. package/src/types/DocumentRef.ts +3 -6
  35. package/src/types/Metadata.ts +23 -2
  36. package/src/types/PresenceEvent.ts +3 -3
  37. package/src/types/RecordRef.ts +28 -1
  38. package/src/utils/ActivityEvents.ts +105 -0
  39. package/src/utils/PresenceEvents.ts +113 -0
@@ -0,0 +1,59 @@
1
+ import type { ActivityEventData, ActivityEventDataCustom, ActivityEventDataUnknown } from "../types/ActivityEvent.js";
2
+ import type { EditDescription, Model, ModelData } from "../types/Model.js";
3
+ /**
4
+ * Creates an edit description to describe an edit for activity purposes, for use with docRef.withTransaction.
5
+ *
6
+ * @param model The model to edit.
7
+ * @param data The data to apply to the model.
8
+ * @returns An edit description for the model.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * docRef.withTransaction(() => {
13
+ * // make some edits to the document here
14
+ * }, ActivityEvents.describeEdit(MyEventModel, {
15
+ * myEventDataField: "some value",
16
+ * foo: 42,
17
+ * }));
18
+ * ```
19
+ */
20
+ export declare function describeEdit<M extends Model>(model: M, data: ModelData<M>): EditDescription<M>;
21
+ /**
22
+ * Type guard for custom event data.
23
+ *
24
+ * @param eventData The event data to check.
25
+ * @returns true if the event data is a custom event, false otherwise.
26
+ */
27
+ export declare function isCustom(eventData: ActivityEventData): eventData is ActivityEventDataCustom;
28
+ /**
29
+ * Type guard for custom event data for a specific model.
30
+ *
31
+ * @param eventData The event data from a {@link ActivityEvent} to check.
32
+ * @param model The model to check for.
33
+ * @returns true if the event data is a custom event for the given model, false otherwise.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * docRef.onActivity((docRef, event) => {
38
+ * if (!ActivityEvents.isEdit(event.eventData, MyEventModel)) {
39
+ * return;
40
+ * }
41
+ *
42
+ * console.log("Got event", event.eventData.eventData.myField);
43
+ * });
44
+ * ```
45
+ */
46
+ export declare function isEdit<M extends Model>(eventData: ActivityEventData, model: M): eventData is ActivityEventDataCustom<M>;
47
+ /**
48
+ * Type guard for unknown activity event data. These are fired when a user
49
+ * performs an action that is not recognized by this client.
50
+ *
51
+ * This may be due to application version mismatch, or new platform features for
52
+ * example, and should generally be ignorable.
53
+ *
54
+ * @experimental
55
+ *
56
+ * @param eventData The event data to check.
57
+ * @returns true if the event data is an unknown event, false otherwise.
58
+ */
59
+ export declare function isUnknown(eventData: ActivityEventData): eventData is ActivityEventDataUnknown;
@@ -0,0 +1 @@
1
+ {"mappings":"AAgBA,cACE,mBACA,yBACA,gCACK;AAEP,cAAc,iBAAiB,OAAO,iBAAiB;;;;;;;;;;;;;;;;;;AAmBvD,OAAO,iBAAS,aAAa,UAAU,OAAO,OAAO,GAAG,MAAM,UAAU,KAAK,gBAAgB;;;;;;;AAa7F,OAAO,iBAAS,SACd,WAAW,oBACV,aAAa;;;;;;;;;;;;;;;;;;;AAsBhB,OAAO,iBAAS,OAAO,UAAU,OAC/B,WAAW,mBACX,OAAO,IACN,aAAa,wBAAwB;;;;;;;;;;;;;AAmBxC,OAAO,iBAAS,UACd,WAAW,oBACV,aAAa","names":[],"sources":["../../../src/utils/ActivityEvents.ts"],"version":3,"file":"ActivityEvents.d.ts"}
@@ -0,0 +1,66 @@
1
+ import type { Model } from "../types/Model.js";
2
+ import type { PresenceEventData, PresenceEventDataArrived, PresenceEventDataCustom, PresenceEventDataDeparted, PresenceEventDataUnknown } from "../types/PresenceEvent.js";
3
+ /**
4
+ * Type guard for Arrived presence events. These are fired when a user comes online on a document.
5
+ * @param eventData The event data from a {@link PresenceEvent} to check.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * if (PresenceEvents.isArrived(event.eventData)) {
10
+ * console.log(`User ${event.userId} has arrived on the document.`);
11
+ * }
12
+ * ```
13
+ */
14
+ export declare function isArrived(eventData: PresenceEventData): eventData is PresenceEventDataArrived;
15
+ /**
16
+ * Type guard for custom presence events.
17
+ * @param eventData The event data from a {@link PresenceEvent} to check.
18
+ * @param model The model to check for.
19
+ * @returns true if the event data is a custom event for the given model, false otherwise.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * if (PresenceEvents.isCustom(event.eventData, MyEventModel)) {
24
+ * console.log("Got event", event.eventData.data.myField);
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function isCustom<M extends Model>(eventData: PresenceEventData, model: M): eventData is PresenceEventDataCustom<M>;
29
+ /**
30
+ * Type guard for custom presence events.
31
+ * @param eventData The event data from a {@link PresenceEvent} to check.
32
+ * @returns true if the event data is a custom event of some type, false otherwise.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * if (PresenceEvents.isCustom(event.eventData)) {
37
+ * console.log("Got a custom event:", event.eventData.model);
38
+ * }
39
+ * ```
40
+ */
41
+ export declare function isCustom(eventData: PresenceEventData): eventData is PresenceEventDataCustom;
42
+ /**
43
+ * Type guard for Departed presence events. These are fired when a user goes offline from a document.
44
+ * @param eventData The event data from a {@link PresenceEvent} to check.
45
+ * @returns true if the event data is a departed event, false otherwise.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * if (PresenceEvents.isDeparted(event.eventData)) {
50
+ * console.log(`User ${event.userId} has departed from the document.`);
51
+ * }
52
+ * ```
53
+ */
54
+ export declare function isDeparted(eventData: PresenceEventData): eventData is PresenceEventDataDeparted;
55
+ /**
56
+ * Type guard for unknown presence events. These are fired when a user performs an action that is not
57
+ * recognized.
58
+ * This may be due to application version mismatch, or new platform features for example, and should
59
+ * generally be ignorable.
60
+ *
61
+ * @experimental
62
+ *
63
+ * @param eventData The event data from a {@link PresenceEvent} to check.
64
+ * @returns true if the event data is an unknown event, false otherwise.
65
+ */
66
+ export declare function isUnknown(eventData: PresenceEventData): eventData is PresenceEventDataUnknown;
@@ -0,0 +1 @@
1
+ {"mappings":"AAgBA,cAAc,aAAa;AAC3B,cACE,mBACA,0BACA,yBACA,2BACA,gCACK;;;;;;;;;;;;AAcP,OAAO,iBAAS,UAAU,WAAW,oBAAoB,aAAa;;;;;;;;;;;;;;AAiBtE,OAAO,iBAAS,SAAS,UAAU,OACjC,WAAW,mBACX,OAAO,IACN,aAAa,wBAAwB;;;;;;;;;;;;;AAaxC,OAAO,iBAAS,SAAS,WAAW,oBAAoB,aAAa;;;;;;;;;;;;;AAuBrE,OAAO,iBAAS,WAAW,WAAW,oBAAoB,aAAa;;;;;;;;;;;;AAevE,OAAO,iBAAS,UACd,WAAW,oBACV,aAAa","names":[],"sources":["../../../src/utils/PresenceEvents.ts"],"version":3,"file":"PresenceEvents.d.ts"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palantir/pack.document-schema.model-types",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Minimal types supporting generated PACK schemas",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
package/src/index.ts CHANGED
@@ -38,7 +38,7 @@ export type {
38
38
  } from "./types/DocumentSchema.js";
39
39
  export { MediaRefBrand } from "./types/MediaRef.js";
40
40
  export type { MediaId, MediaRef } from "./types/MediaRef.js";
41
- export { getMetadata, Metadata } from "./types/Metadata.js";
41
+ export { getMetadata, hasMetadata, Metadata } from "./types/Metadata.js";
42
42
  export type { WithMetadata } from "./types/Metadata.js";
43
43
  export { ExternalRefType } from "./types/Model.js";
44
44
  export type { EditDescription, Model, ModelData, ModelMetadata } from "./types/Model.js";
@@ -51,7 +51,7 @@ export type {
51
51
  PresenceEventDataArrived,
52
52
  PresenceEventDataCustom,
53
53
  PresenceEventDataDeparted,
54
- PresenceEventUnknown,
54
+ PresenceEventDataUnknown,
55
55
  } from "./types/PresenceEvent.js";
56
56
  export { RecordCollectionRefBrand } from "./types/RecordCollectionRef.js";
57
57
  export type { RecordCollectionRef } from "./types/RecordCollectionRef.js";
@@ -60,3 +60,5 @@ export type { RecordId, RecordRef } from "./types/RecordRef.js";
60
60
  export type { Unsubscribe } from "./types/Unsubscribe.js";
61
61
  export { UserRefBrand } from "./types/UserRef.js";
62
62
  export type { UserId, UserRef } from "./types/UserRef.js";
63
+ export * as ActivityEvents from "./utils/ActivityEvents.js";
64
+ export * as PresenceEvents from "./utils/PresenceEvents.js";
@@ -63,7 +63,7 @@ export interface ActivityEventDataCustom<M extends Model = Model> {
63
63
  * applications.
64
64
  */
65
65
  export interface ActivityEventDataUnknown {
66
- readonly type: "unknown";
66
+ readonly type: typeof ActivityEventDataType.UNKNOWN;
67
67
  readonly rawType: string;
68
68
  readonly rawData: unknown;
69
69
  }
@@ -239,12 +239,9 @@ export interface DocumentRef<D extends DocumentSchema = DocumentSchema> {
239
239
  * const myRecords = docRef.getRecords(MyModel);
240
240
  * myRecords.set("record-1", { field: "new value" });
241
241
  * myRecords.delete("record-2");
242
- * }, {
243
- * model: MyEditEventModel,
244
- * data: {
245
- * summary: "Updated record-1 and deleted record-2",
246
- * },
247
- * });
242
+ * }, ActivityEvents.describeEdit(MyEditEventModel, {
243
+ * summary: "Updated record-1 and deleted record-2",
244
+ * }));
248
245
  * ```
249
246
  */
250
247
  withTransaction(fn: () => void, description?: EditDescription): void;
@@ -14,13 +14,17 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { justOnce } from "@palantir/pack.core";
18
+
17
19
  export const Metadata: symbol = Symbol("@palantir/pack.document-schema/metadata");
18
20
 
19
21
  export interface WithMetadata<T> {
20
22
  readonly [Metadata]: T;
21
23
  }
22
24
 
23
- export function getMetadata<T>(obj: WithMetadata<T>): T {
25
+ export function getMetadata<T>(obj: WithMetadata<T>, throwIfMissing?: true): T;
26
+ export function getMetadata<T>(obj: WithMetadata<T>, throwIfMissing: false): T | undefined;
27
+ export function getMetadata<T>(obj: WithMetadata<T>, throwIfMissing = true): T | undefined {
24
28
  // First try the direct symbol access
25
29
  const directMetadata = obj[Metadata];
26
30
  if (directMetadata != null) {
@@ -36,10 +40,27 @@ export function getMetadata<T>(obj: WithMetadata<T>): T {
36
40
  if (symbolKey.toString() === metadataString) {
37
41
  const fallbackMetadata = (obj as any)[symbolKey];
38
42
  if (fallbackMetadata != null) {
43
+ justOnce("getMetadata-fallback-warning", () => {
44
+ // eslint-disable-next-line no-console
45
+ console.warn(
46
+ "Warning: Retrieved metadata using fallback symbol lookup. "
47
+ + "This may indicate that multiple copies of the @palantir/pack.document-schema.model-types package are in use. "
48
+ + "Consider deduplicating your dependencies and checking bundle configurations to ensure proper behavior.",
49
+ );
50
+ });
39
51
  return fallbackMetadata;
40
52
  }
41
53
  }
42
54
  }
43
55
 
44
- throw new Error("Object does not have metadata");
56
+ if (throwIfMissing) {
57
+ throw new Error("Object does not have metadata");
58
+ }
59
+ }
60
+
61
+ export function hasMetadata(obj: unknown): obj is WithMetadata<unknown> {
62
+ if (obj == null || typeof obj !== "object") {
63
+ return false;
64
+ }
65
+ return getMetadata(obj as WithMetadata<unknown>, false) != null;
45
66
  }
@@ -74,8 +74,8 @@ export interface PresenceEventDataCustom<M extends Model = Model> {
74
74
  * in a future release of pack libraries and can be safely ignored by
75
75
  * applications.
76
76
  */
77
- export interface PresenceEventUnknown {
78
- readonly type: "unknown";
77
+ export interface PresenceEventDataUnknown {
78
+ readonly type: typeof PresenceEventDataType.UNKNOWN;
79
79
  readonly rawType: string;
80
80
  readonly rawData: unknown;
81
81
  }
@@ -84,7 +84,7 @@ export type PresenceEventData =
84
84
  | PresenceEventDataArrived
85
85
  | PresenceEventDataDeparted
86
86
  | PresenceEventDataCustom
87
- | PresenceEventUnknown;
87
+ | PresenceEventDataUnknown;
88
88
 
89
89
  /**
90
90
  * An event representing a transient awareness or presence change for a user on this document.
@@ -88,11 +88,23 @@ export interface RecordRef<M extends Model = Model> {
88
88
  * });
89
89
  *
90
90
  * // Trigger the deletion
91
- * docRef.getRecords(MyModel).delete(recordRef.id);
91
+ * recordRef.delete();
92
92
  * ```
93
93
  */
94
94
  onDeleted(callback: (recordRef: RecordRef<M>) => void): Unsubscribe;
95
95
 
96
+ /**
97
+ * Delete the record from the document.
98
+ *
99
+ * @returns An ignorable promise that resolves when the record is deleted.
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * await recordRef.delete();
104
+ * ```
105
+ */
106
+ delete(): Promise<void>;
107
+
96
108
  /**
97
109
  * Set the data for the record (creating it if it doesn't exist).
98
110
  *
@@ -107,4 +119,19 @@ export interface RecordRef<M extends Model = Model> {
107
119
  * ```
108
120
  */
109
121
  set(record: ModelData<M>): Promise<void>;
122
+
123
+ /**
124
+ * Update specific fields of the record.
125
+ *
126
+ * @see {onChange} to subscribe to changes to the record.
127
+ *
128
+ * @param partialRecord - A partial plain object with the fields to update.
129
+ * @returns An ignorable promise that resolves when the record is published.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * await recordRef.update({ field: "new value" });
134
+ * ```
135
+ */
136
+ update(record: Partial<ModelData<M>>): Promise<void>;
110
137
  }
@@ -0,0 +1,105 @@
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
+ ActivityEventData,
19
+ ActivityEventDataCustom,
20
+ ActivityEventDataUnknown,
21
+ } from "../types/ActivityEvent.js";
22
+ import { ActivityEventDataType } from "../types/ActivityEvent.js";
23
+ import type { EditDescription, Model, ModelData } from "../types/Model.js";
24
+
25
+ /**
26
+ * Creates an edit description to describe an edit for activity purposes, for use with docRef.withTransaction.
27
+ *
28
+ * @param model The model to edit.
29
+ * @param data The data to apply to the model.
30
+ * @returns An edit description for the model.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * docRef.withTransaction(() => {
35
+ * // make some edits to the document here
36
+ * }, ActivityEvents.describeEdit(MyEventModel, {
37
+ * myEventDataField: "some value",
38
+ * foo: 42,
39
+ * }));
40
+ * ```
41
+ */
42
+ export function describeEdit<M extends Model>(model: M, data: ModelData<M>): EditDescription<M> {
43
+ return {
44
+ data,
45
+ model,
46
+ };
47
+ }
48
+
49
+ /**
50
+ * Type guard for custom event data.
51
+ *
52
+ * @param eventData The event data to check.
53
+ * @returns true if the event data is a custom event, false otherwise.
54
+ */
55
+ export function isCustom(
56
+ eventData: ActivityEventData,
57
+ ): eventData is ActivityEventDataCustom {
58
+ return eventData.type === ActivityEventDataType.CUSTOM_EVENT;
59
+ }
60
+
61
+ /**
62
+ * Type guard for custom event data for a specific model.
63
+ *
64
+ * @param eventData The event data from a {@link ActivityEvent} to check.
65
+ * @param model The model to check for.
66
+ * @returns true if the event data is a custom event for the given model, false otherwise.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * docRef.onActivity((docRef, event) => {
71
+ * if (!ActivityEvents.isEdit(event.eventData, MyEventModel)) {
72
+ * return;
73
+ * }
74
+ *
75
+ * console.log("Got event", event.eventData.eventData.myField);
76
+ * });
77
+ * ```
78
+ */
79
+ export function isEdit<M extends Model>(
80
+ eventData: ActivityEventData,
81
+ model: M,
82
+ ): eventData is ActivityEventDataCustom<M> {
83
+ return (
84
+ eventData.type === ActivityEventDataType.CUSTOM_EVENT
85
+ && eventData.model === model
86
+ );
87
+ }
88
+
89
+ /**
90
+ * Type guard for unknown activity event data. These are fired when a user
91
+ * performs an action that is not recognized by this client.
92
+ *
93
+ * This may be due to application version mismatch, or new platform features for
94
+ * example, and should generally be ignorable.
95
+ *
96
+ * @experimental
97
+ *
98
+ * @param eventData The event data to check.
99
+ * @returns true if the event data is an unknown event, false otherwise.
100
+ */
101
+ export function isUnknown(
102
+ eventData: ActivityEventData,
103
+ ): eventData is ActivityEventDataUnknown {
104
+ return eventData.type === ActivityEventDataType.UNKNOWN;
105
+ }
@@ -0,0 +1,113 @@
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 { Model } from "../types/Model.js";
18
+ import type {
19
+ PresenceEventData,
20
+ PresenceEventDataArrived,
21
+ PresenceEventDataCustom,
22
+ PresenceEventDataDeparted,
23
+ PresenceEventDataUnknown,
24
+ } from "../types/PresenceEvent.js";
25
+ import { PresenceEventDataType } from "../types/PresenceEvent.js";
26
+
27
+ /**
28
+ * Type guard for Arrived presence events. These are fired when a user comes online on a document.
29
+ * @param eventData The event data from a {@link PresenceEvent} to check.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * if (PresenceEvents.isArrived(event.eventData)) {
34
+ * console.log(`User ${event.userId} has arrived on the document.`);
35
+ * }
36
+ * ```
37
+ */
38
+ export function isArrived(eventData: PresenceEventData): eventData is PresenceEventDataArrived {
39
+ return eventData.type === PresenceEventDataType.ARRIVED;
40
+ }
41
+
42
+ /**
43
+ * Type guard for custom presence events.
44
+ * @param eventData The event data from a {@link PresenceEvent} to check.
45
+ * @param model The model to check for.
46
+ * @returns true if the event data is a custom event for the given model, false otherwise.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * if (PresenceEvents.isCustom(event.eventData, MyEventModel)) {
51
+ * console.log("Got event", event.eventData.data.myField);
52
+ * }
53
+ * ```
54
+ */
55
+ export function isCustom<M extends Model>(
56
+ eventData: PresenceEventData,
57
+ model: M,
58
+ ): eventData is PresenceEventDataCustom<M>;
59
+ /**
60
+ * Type guard for custom presence events.
61
+ * @param eventData The event data from a {@link PresenceEvent} to check.
62
+ * @returns true if the event data is a custom event of some type, false otherwise.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * if (PresenceEvents.isCustom(event.eventData)) {
67
+ * console.log("Got a custom event:", event.eventData.model);
68
+ * }
69
+ * ```
70
+ */
71
+ export function isCustom(eventData: PresenceEventData): eventData is PresenceEventDataCustom;
72
+ export function isCustom<M extends Model>(
73
+ eventData: PresenceEventData,
74
+ model?: M,
75
+ ): eventData is PresenceEventDataCustom<M> {
76
+ return (
77
+ eventData.type === PresenceEventDataType.CUSTOM_EVENT
78
+ && (model == null || eventData.model === model)
79
+ );
80
+ }
81
+
82
+ /**
83
+ * Type guard for Departed presence events. These are fired when a user goes offline from a document.
84
+ * @param eventData The event data from a {@link PresenceEvent} to check.
85
+ * @returns true if the event data is a departed event, false otherwise.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * if (PresenceEvents.isDeparted(event.eventData)) {
90
+ * console.log(`User ${event.userId} has departed from the document.`);
91
+ * }
92
+ * ```
93
+ */
94
+ export function isDeparted(eventData: PresenceEventData): eventData is PresenceEventDataDeparted {
95
+ return eventData.type === PresenceEventDataType.DEPARTED;
96
+ }
97
+
98
+ /**
99
+ * Type guard for unknown presence events. These are fired when a user performs an action that is not
100
+ * recognized.
101
+ * This may be due to application version mismatch, or new platform features for example, and should
102
+ * generally be ignorable.
103
+ *
104
+ * @experimental
105
+ *
106
+ * @param eventData The event data from a {@link PresenceEvent} to check.
107
+ * @returns true if the event data is an unknown event, false otherwise.
108
+ */
109
+ export function isUnknown(
110
+ eventData: PresenceEventData,
111
+ ): eventData is PresenceEventDataUnknown {
112
+ return eventData.type === PresenceEventDataType.UNKNOWN;
113
+ }