mobx-keystone-yjs 1.5.4 → 1.6.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +57 -45
  2. package/dist/mobx-keystone-yjs.esm.js +475 -299
  3. package/dist/mobx-keystone-yjs.esm.mjs +475 -299
  4. package/dist/mobx-keystone-yjs.umd.js +475 -299
  5. package/dist/types/binding/YjsTextModel.d.ts +5 -4
  6. package/dist/types/binding/applyMobxChangeToYjsObject.d.ts +3 -0
  7. package/dist/types/binding/applyYjsEventToMobx.d.ts +8 -0
  8. package/dist/types/binding/bindYjsToMobxKeystone.d.ts +1 -1
  9. package/dist/types/binding/convertJsonToYjsData.d.ts +23 -4
  10. package/dist/types/binding/convertYjsDataToJson.d.ts +1 -1
  11. package/dist/types/binding/resolveYjsPath.d.ts +14 -1
  12. package/dist/types/binding/yjsBindingContext.d.ts +2 -2
  13. package/dist/types/binding/yjsSnapshotTracking.d.ts +24 -0
  14. package/dist/types/index.d.ts +7 -6
  15. package/dist/types/utils/isYjsValueDeleted.d.ts +7 -0
  16. package/package.json +90 -78
  17. package/src/binding/YjsTextModel.ts +280 -247
  18. package/src/binding/applyMobxChangeToYjsObject.ts +77 -0
  19. package/src/binding/applyYjsEventToMobx.ts +173 -0
  20. package/src/binding/bindYjsToMobxKeystone.ts +300 -192
  21. package/src/binding/convertJsonToYjsData.ts +218 -76
  22. package/src/binding/convertYjsDataToJson.ts +1 -1
  23. package/src/binding/resolveYjsPath.ts +51 -27
  24. package/src/binding/yjsSnapshotTracking.ts +40 -0
  25. package/src/index.ts +11 -10
  26. package/src/utils/getOrCreateYjsCollectionAtom.ts +27 -27
  27. package/src/utils/isYjsValueDeleted.ts +14 -0
  28. package/dist/types/binding/applyMobxKeystonePatchToYjsObject.d.ts +0 -2
  29. package/dist/types/binding/convertYjsEventToPatches.d.ts +0 -3
  30. package/src/binding/applyMobxKeystonePatchToYjsObject.ts +0 -98
  31. package/src/binding/convertYjsEventToPatches.ts +0 -92
@@ -1,9 +1,9 @@
1
- import { IAtom } from "mobx";
2
- import { Frozen } from "mobx-keystone";
1
+ import { IAtom } from 'mobx';
2
+ import { Frozen } from 'mobx-keystone';
3
3
  import * as Y from "yjs";
4
4
  export declare const yjsTextModelId = "mobx-keystone-yjs/YjsTextModel";
5
- declare const YjsTextModel_base: import("mobx-keystone")._Model<unknown, {
6
- deltaList: import("mobx-keystone").OptionalModelProp<Frozen<unknown[]>[]>;
5
+ declare const YjsTextModel_base: import('mobx-keystone')._Model<unknown, {
6
+ deltaList: import('mobx-keystone').OptionalModelProp<Frozen<unknown[]>[]>;
7
7
  }, never, never>;
8
8
  /**
9
9
  * A mobx-keystone model that represents a Yjs.Text object.
@@ -34,6 +34,7 @@ export declare class YjsTextModel extends YjsTextModel_base {
34
34
  * Shortcut for `yjsText.toString()`, but computed.
35
35
  */
36
36
  get text(): string;
37
+ private deltaListToText;
37
38
  protected onInit(): () => void;
38
39
  }
39
40
  export {};
@@ -0,0 +1,3 @@
1
+ import { DeepChange } from 'mobx-keystone';
2
+ import * as Y from "yjs";
3
+ export declare function applyMobxChangeToYjsObject(change: DeepChange, yjsObject: Y.Map<any> | Y.Array<any> | Y.Text): void;
@@ -0,0 +1,8 @@
1
+ import * as Y from "yjs";
2
+ export type ReconciliationMap = Map<string, object>;
3
+ /**
4
+ * Applies a Y.js event directly to the MobX model tree using proper mutations
5
+ * (splice for arrays, property assignment for objects).
6
+ * This is more efficient than converting to patches first.
7
+ */
8
+ export declare function applyYjsEventToMobx(event: Y.YEvent<any>, boundObject: object, reconciliationMap: ReconciliationMap): void;
@@ -1,4 +1,4 @@
1
- import { AnyDataModel, AnyModel, AnyStandardType, ModelClass, TypeToData } from "mobx-keystone";
1
+ import { AnyDataModel, AnyModel, AnyStandardType, ModelClass, TypeToData } from 'mobx-keystone';
2
2
  import * as Y from "yjs";
3
3
  /**
4
4
  * Creates a bidirectional binding between a Y.js data structure and a mobx-keystone model.
@@ -1,6 +1,17 @@
1
+ import { PlainArray, PlainObject, PlainValue } from '../plainTypes';
2
+ import { YjsData } from './convertYjsDataToJson';
1
3
  import * as Y from "yjs";
2
- import { YjsData } from "./convertYjsDataToJson";
3
- import { PlainArray, PlainObject, PlainValue } from "../plainTypes";
4
+ /**
5
+ * Options for applying JSON data to Y.js data structures.
6
+ */
7
+ export interface ApplyJsonToYjsOptions {
8
+ /**
9
+ * The mode to use when applying JSON data to Y.js data structures.
10
+ * - `add`: Creates new Y.js containers for objects/arrays (default, backwards compatible)
11
+ * - `merge`: Recursively merges values, preserving existing container references where possible
12
+ */
13
+ mode?: "add" | "merge";
14
+ }
4
15
  /**
5
16
  * Converts a plain value to a Y.js data structure.
6
17
  * Objects are converted to Y.Maps, arrays to Y.Arrays, primitives are untouched.
@@ -9,9 +20,17 @@ import { PlainArray, PlainObject, PlainValue } from "../plainTypes";
9
20
  export declare function convertJsonToYjsData(v: PlainValue): YjsData;
10
21
  /**
11
22
  * Applies a JSON array to a Y.Array, using the convertJsonToYjsData to convert the values.
23
+ *
24
+ * @param dest The destination Y.Array.
25
+ * @param source The source JSON array.
26
+ * @param options Options for applying the JSON data.
12
27
  */
13
- export declare const applyJsonArrayToYArray: (dest: Y.Array<any>, source: PlainArray) => void;
28
+ export declare const applyJsonArrayToYArray: (dest: Y.Array<any>, source: PlainArray, options?: ApplyJsonToYjsOptions) => void;
14
29
  /**
15
30
  * Applies a JSON object to a Y.Map, using the convertJsonToYjsData to convert the values.
31
+ *
32
+ * @param dest The destination Y.Map.
33
+ * @param source The source JSON object.
34
+ * @param options Options for applying the JSON data.
16
35
  */
17
- export declare const applyJsonObjectToYMap: (dest: Y.Map<any>, source: PlainObject) => void;
36
+ export declare const applyJsonObjectToYMap: (dest: Y.Map<any>, source: PlainObject, options?: ApplyJsonToYjsOptions) => void;
@@ -1,4 +1,4 @@
1
+ import { PlainValue } from '../plainTypes';
1
2
  import * as Y from "yjs";
2
- import { PlainValue } from "../plainTypes";
3
3
  export type YjsData = Y.Array<any> | Y.Map<any> | Y.Text | PlainValue;
4
4
  export declare const convertYjsDataToJson: (yjsData: YjsData) => PlainValue;
@@ -1 +1,14 @@
1
- export declare function resolveYjsPath(yjsObject: unknown, path: readonly (string | number)[]): unknown;
1
+ import * as Y from "yjs";
2
+ /**
3
+ * Resolves a path within a Yjs object structure.
4
+ * Returns the Yjs container at the specified path.
5
+ *
6
+ * When a Y.Text is encountered during path resolution (either at the start
7
+ * or mid-path), it is returned immediately since Y.Text doesn't support
8
+ * nested path traversal.
9
+ *
10
+ * @param yjsObject The root Yjs object
11
+ * @param path Array of keys/indices to traverse
12
+ * @returns The Yjs container at the path, or Y.Text if encountered during traversal
13
+ */
14
+ export declare function resolveYjsPath(yjsObject: Y.Map<unknown> | Y.Array<unknown> | Y.Text, path: readonly (string | number)[]): unknown;
@@ -1,4 +1,4 @@
1
- import { AnyType } from "mobx-keystone";
1
+ import { AnyType } from 'mobx-keystone';
2
2
  import * as Y from "yjs";
3
3
  /**
4
4
  * Context with info on how a mobx-keystone model is bound to a Y.js data structure.
@@ -32,4 +32,4 @@ export interface YjsBindingContext {
32
32
  /**
33
33
  * Context with info on how a mobx-keystone model is bound to a Y.js data structure.
34
34
  */
35
- export declare const yjsBindingContext: import("mobx-keystone").Context<YjsBindingContext | undefined>;
35
+ export declare const yjsBindingContext: import('mobx-keystone').Context<YjsBindingContext | undefined>;
@@ -0,0 +1,24 @@
1
+ import * as Y from "yjs";
2
+ /**
3
+ * WeakMap that tracks which snapshot each Y.js container was last synced from.
4
+ * This is used during reconciliation to skip containers that are already up-to-date.
5
+ *
6
+ * The key is the Y.js container (Y.Map or Y.Array).
7
+ * The value is the snapshot (plain object or array) that was last synced to it.
8
+ */
9
+ export declare const yjsContainerToSnapshot: WeakMap<Y.Map<any> | Y.Array<any>, unknown>;
10
+ /**
11
+ * Updates the snapshot tracking for a Y.js container.
12
+ * Call this after syncing a snapshot to a Y.js container.
13
+ */
14
+ export declare function setYjsContainerSnapshot(container: Y.Map<any> | Y.Array<any>, snapshot: unknown): void;
15
+ /**
16
+ * Gets the last synced snapshot for a Y.js container.
17
+ * Returns undefined if the container has never been synced.
18
+ */
19
+ export declare function getYjsContainerSnapshot(container: Y.Map<any> | Y.Array<any>): unknown;
20
+ /**
21
+ * Checks if a Y.js container is up-to-date with the given snapshot.
22
+ * Uses reference equality to check if the snapshot is the same.
23
+ */
24
+ export declare function isYjsContainerUpToDate(container: Y.Map<any> | Y.Array<any>, snapshot: unknown): boolean;
@@ -1,6 +1,7 @@
1
- export { YjsTextModel, yjsTextModelId } from "./binding/YjsTextModel";
2
- export { bindYjsToMobxKeystone } from "./binding/bindYjsToMobxKeystone";
3
- export { applyJsonArrayToYArray, applyJsonObjectToYMap, convertJsonToYjsData, } from "./binding/convertJsonToYjsData";
4
- export { yjsBindingContext } from "./binding/yjsBindingContext";
5
- export type { YjsBindingContext } from "./binding/yjsBindingContext";
6
- export { MobxKeystoneYjsError } from "./utils/error";
1
+ export { bindYjsToMobxKeystone } from './binding/bindYjsToMobxKeystone';
2
+ export type { ApplyJsonToYjsOptions } from './binding/convertJsonToYjsData';
3
+ export { applyJsonArrayToYArray, applyJsonObjectToYMap, convertJsonToYjsData, } from './binding/convertJsonToYjsData';
4
+ export { YjsTextModel, yjsTextModelId } from './binding/YjsTextModel';
5
+ export type { YjsBindingContext } from './binding/yjsBindingContext';
6
+ export { yjsBindingContext } from './binding/yjsBindingContext';
7
+ export { MobxKeystoneYjsError } from './utils/error';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Checks if a Y.js value has been deleted or its document destroyed.
3
+ *
4
+ * @param yjsValue The Y.js value to check.
5
+ * @returns `true` if the value is deleted or destroyed, `false` otherwise.
6
+ */
7
+ export declare function isYjsValueDeleted(yjsValue: unknown): boolean;
package/package.json CHANGED
@@ -1,78 +1,90 @@
1
- {
2
- "name": "mobx-keystone-yjs",
3
- "version": "1.5.4",
4
- "description": "Yjs bindings for mobx-keystone",
5
- "keywords": ["mobx", "mobx-keystone", "yjs", "crdt", "state management"],
6
- "repository": {
7
- "type": "git",
8
- "url": "https://github.com/xaviergonz/mobx-keystone.git"
9
- },
10
- "bugs": {
11
- "url": "https://github.com/xaviergonz/mobx-keystone/issues"
12
- },
13
- "homepage": "https://mobx-keystone.js.org",
14
- "license": "MIT",
15
- "author": "Javier González Garcés",
16
- "source": "./src/index.ts",
17
- "exports": {
18
- "./package.json": "./package.json",
19
- ".": {
20
- "types": "./dist/types/index.d.ts",
21
- "script": "./dist/mobx-keystone-yjs.umd.js",
22
- "import": "./dist/mobx-keystone-yjs.esm.mjs",
23
- "require": "./dist/mobx-keystone-yjs.umd.js",
24
- "default": "./dist/mobx-keystone-yjs.esm.mjs"
25
- }
26
- },
27
- "esmodule": "./dist/mobx-keystone-yjs.esm.js",
28
- "module": "./dist/mobx-keystone-yjs.esm.js",
29
- "jsnext:main": "./dist/mobx-keystone-yjs.esm.js",
30
- "react-native": "./dist/mobx-keystone-yjs.umd.js",
31
- "umd:main": "./dist/mobx-keystone-yjs.umd.js",
32
- "unpkg": "./dist/mobx-keystone-yjs.umd.js",
33
- "jsdelivr": "./dist/mobx-keystone-yjs.umd.js",
34
- "main": "./dist/mobx-keystone-yjs.umd.js",
35
- "types": "./dist/types/index.d.ts",
36
- "typings": "./dist/types/index.d.ts",
37
- "sideEffects": false,
38
- "files": ["src", "dist", "LICENSE", "CHANGELOG.md", "README.md"],
39
- "scripts": {
40
- "quick-build": "tsc",
41
- "quick-build-tests": "tsc -p test",
42
- "copy-root-files": "shx cp ../../LICENSE .",
43
- "build": "yarn quick-build && yarn copy-root-files && shx rm -rf dist && vite build && shx cp dist/mobx-keystone-yjs.esm.mjs dist/mobx-keystone-yjs.esm.js",
44
- "test": "jest",
45
- "test:ci": "yarn test -i",
46
- "test:perf": "yarn build && yarn test:perf:run"
47
- },
48
- "peerDependencies": {
49
- "mobx": "^6.0.0 || ^5.0.0 || ^4.0.0",
50
- "mobx-keystone": "^1.9.0",
51
- "yjs": "^13.0.0"
52
- },
53
- "devDependencies": {
54
- "@babel/core": "^7.26.8",
55
- "@babel/plugin-proposal-class-properties": "^7.18.6",
56
- "@babel/plugin-proposal-decorators": "^7.25.9",
57
- "@babel/preset-env": "^7.26.8",
58
- "@babel/preset-typescript": "^7.26.0",
59
- "@types/jest": "^29.5.14",
60
- "@types/node": "^22.13.1",
61
- "babel-jest": "^29.7.0",
62
- "jest": "^29.7.0",
63
- "mobx-keystone": "workspace:packages/lib",
64
- "rollup-plugin-typescript2": "^0.36.0",
65
- "shx": "^0.3.4",
66
- "spec.ts": "^1.1.3",
67
- "ts-jest": "^29.2.5",
68
- "ts-node": "^10.9.2",
69
- "typescript": "^5.7.3",
70
- "vite": "^6.1.0"
71
- },
72
- "dependencies": {
73
- "tslib": "^2.8.1"
74
- },
75
- "directories": {
76
- "test": "test"
77
- }
78
- }
1
+ {
2
+ "name": "mobx-keystone-yjs",
3
+ "version": "1.6.0",
4
+ "description": "Yjs bindings for mobx-keystone",
5
+ "keywords": [
6
+ "mobx",
7
+ "mobx-keystone",
8
+ "yjs",
9
+ "crdt",
10
+ "state",
11
+ "state-management",
12
+ "reactive",
13
+ "collaborative"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/xaviergonz/mobx-keystone.git"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/xaviergonz/mobx-keystone/issues"
21
+ },
22
+ "homepage": "https://mobx-keystone.js.org",
23
+ "license": "MIT",
24
+ "author": "Javier González Garcés",
25
+ "source": "./src/index.ts",
26
+ "exports": {
27
+ "./package.json": "./package.json",
28
+ ".": {
29
+ "types": "./dist/types/index.d.ts",
30
+ "script": "./dist/mobx-keystone-yjs.umd.js",
31
+ "import": "./dist/mobx-keystone-yjs.esm.mjs",
32
+ "require": "./dist/mobx-keystone-yjs.umd.js",
33
+ "default": "./dist/mobx-keystone-yjs.esm.mjs"
34
+ }
35
+ },
36
+ "esmodule": "./dist/mobx-keystone-yjs.esm.js",
37
+ "module": "./dist/mobx-keystone-yjs.esm.js",
38
+ "jsnext:main": "./dist/mobx-keystone-yjs.esm.js",
39
+ "react-native": "./dist/mobx-keystone-yjs.umd.js",
40
+ "umd:main": "./dist/mobx-keystone-yjs.umd.js",
41
+ "unpkg": "./dist/mobx-keystone-yjs.umd.js",
42
+ "jsdelivr": "./dist/mobx-keystone-yjs.umd.js",
43
+ "main": "./dist/mobx-keystone-yjs.umd.js",
44
+ "types": "./dist/types/index.d.ts",
45
+ "typings": "./dist/types/index.d.ts",
46
+ "sideEffects": false,
47
+ "files": [
48
+ "src",
49
+ "dist",
50
+ "LICENSE",
51
+ "CHANGELOG.md",
52
+ "README.md"
53
+ ],
54
+ "scripts": {
55
+ "quick-build": "tsc",
56
+ "quick-build-tests": "tsc -p test",
57
+ "copy-root-files": "shx cp ../../LICENSE .",
58
+ "build": "yarn quick-build && yarn copy-root-files && shx rm -rf dist && vite build && shx cp dist/mobx-keystone-yjs.esm.mjs dist/mobx-keystone-yjs.esm.js",
59
+ "test": "jest",
60
+ "test:ci": "yarn test -i"
61
+ },
62
+ "peerDependencies": {
63
+ "mobx": "^6.0.0 || ^5.0.0 || ^4.0.0",
64
+ "mobx-keystone": "^1.12.0",
65
+ "yjs": "^13.0.0"
66
+ },
67
+ "devDependencies": {
68
+ "@babel/core": "^7.28.5",
69
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
70
+ "@babel/plugin-proposal-decorators": "^7.28.0",
71
+ "@babel/preset-env": "^7.28.5",
72
+ "@babel/preset-typescript": "^7.28.5",
73
+ "@types/jest": "^30.0.0",
74
+ "@types/node": "^25.0.3",
75
+ "babel-jest": "^30.2.0",
76
+ "jest": "^30.2.0",
77
+ "mobx-keystone": "workspace:packages/lib",
78
+ "shx": "^0.4.0",
79
+ "spec.ts": "^1.1.3",
80
+ "ts-jest": "^29.4.6",
81
+ "ts-node": "^10.9.2",
82
+ "typescript": "^5.9.3"
83
+ },
84
+ "dependencies": {
85
+ "tslib": "^2.8.1"
86
+ },
87
+ "directories": {
88
+ "test": "test"
89
+ }
90
+ }