@kokimoki/app 1.13.0 → 1.14.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.
@@ -486,7 +486,7 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
486
486
  var eventsExports = events.exports;
487
487
  var EventEmitter$1 = /*@__PURE__*/getDefaultExportFromCjs(eventsExports);
488
488
 
489
- const KOKIMOKI_APP_VERSION = "1.13.0";
489
+ const KOKIMOKI_APP_VERSION = "1.14.0";
490
490
 
491
491
  /**
492
492
  * Utility module to work with key-value stores.
@@ -508,9 +508,9 @@ const create$5 = () => new Map();
508
508
  * Copy a Map object into a fresh Map object.
509
509
  *
510
510
  * @function
511
- * @template X,Y
512
- * @param {Map<X,Y>} m
513
- * @return {Map<X,Y>}
511
+ * @template K,V
512
+ * @param {Map<K,V>} m
513
+ * @return {Map<K,V>}
514
514
  */
515
515
  const copy = m => {
516
516
  const r = create$5();
@@ -527,12 +527,12 @@ const copy = m => {
527
527
  * ```
528
528
  *
529
529
  * @function
530
- * @template V,K
531
- * @template {Map<K,V>} MAP
530
+ * @template {Map<any, any>} MAP
531
+ * @template {MAP extends Map<any,infer V> ? function():V : unknown} CF
532
532
  * @param {MAP} map
533
- * @param {K} key
534
- * @param {function():V} createT
535
- * @return {V}
533
+ * @param {MAP extends Map<infer K,any> ? K : unknown} key
534
+ * @param {CF} createT
535
+ * @return {ReturnType<CF>}
536
536
  */
537
537
  const setIfUndefined = (map, key, createT) => {
538
538
  let set = map.get(key);
@@ -640,44 +640,52 @@ const isArray = Array.isArray;
640
640
 
641
641
  /**
642
642
  * Handles named events.
643
+ * @experimental
644
+ *
645
+ * This is basically a (better typed) duplicate of Observable, which will replace Observable in the
646
+ * next release.
643
647
  *
644
- * @template N
648
+ * @template {{[key in keyof EVENTS]: function(...any):void}} EVENTS
645
649
  */
646
- class Observable {
650
+ class ObservableV2 {
647
651
  constructor () {
648
652
  /**
649
653
  * Some desc.
650
- * @type {Map<N, any>}
654
+ * @type {Map<string, Set<any>>}
651
655
  */
652
656
  this._observers = create$5();
653
657
  }
654
658
 
655
659
  /**
656
- * @param {N} name
657
- * @param {function} f
660
+ * @template {keyof EVENTS & string} NAME
661
+ * @param {NAME} name
662
+ * @param {EVENTS[NAME]} f
658
663
  */
659
664
  on (name, f) {
660
- setIfUndefined(this._observers, name, create$4).add(f);
665
+ setIfUndefined(this._observers, /** @type {string} */ (name), create$4).add(f);
666
+ return f
661
667
  }
662
668
 
663
669
  /**
664
- * @param {N} name
665
- * @param {function} f
670
+ * @template {keyof EVENTS & string} NAME
671
+ * @param {NAME} name
672
+ * @param {EVENTS[NAME]} f
666
673
  */
667
674
  once (name, f) {
668
675
  /**
669
676
  * @param {...any} args
670
677
  */
671
678
  const _f = (...args) => {
672
- this.off(name, _f);
679
+ this.off(name, /** @type {any} */ (_f));
673
680
  f(...args);
674
681
  };
675
- this.on(name, _f);
682
+ this.on(name, /** @type {any} */ (_f));
676
683
  }
677
684
 
678
685
  /**
679
- * @param {N} name
680
- * @param {function} f
686
+ * @template {keyof EVENTS & string} NAME
687
+ * @param {NAME} name
688
+ * @param {EVENTS[NAME]} f
681
689
  */
682
690
  off (name, f) {
683
691
  const observers = this._observers.get(name);
@@ -695,8 +703,9 @@ class Observable {
695
703
  *
696
704
  * @todo This should catch exceptions
697
705
  *
698
- * @param {N} name The event name.
699
- * @param {Array<any>} args The arguments that are applied to the event listener.
706
+ * @template {keyof EVENTS & string} NAME
707
+ * @param {NAME} name The event name.
708
+ * @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener.
700
709
  */
701
710
  emit (name, args) {
702
711
  // copy all listeners to an array first to make sure that no event is emitted to listeners that are subscribed while the event handler is called.
@@ -707,6 +716,7 @@ class Observable {
707
716
  this._observers = create$5();
708
717
  }
709
718
  }
719
+ /* c8 ignore end */
710
720
 
711
721
  /**
712
722
  * Common Math expressions.
@@ -739,6 +749,46 @@ const max$3 = (a, b) => a > b ? a : b;
739
749
  */
740
750
  const isNegativeZero = n => n !== 0 ? n < 0 : 1 / n < 0;
741
751
 
752
+ /* eslint-env browser */
753
+
754
+ /**
755
+ * Binary data constants.
756
+ *
757
+ * @module binary
758
+ */
759
+
760
+ /**
761
+ * n-th bit activated.
762
+ *
763
+ * @type {number}
764
+ */
765
+ const BIT1 = 1;
766
+ const BIT2 = 2;
767
+ const BIT3 = 4;
768
+ const BIT4 = 8;
769
+ const BIT6 = 32;
770
+ const BIT7 = 64;
771
+ const BIT8 = 128;
772
+ const BITS5 = 31;
773
+ const BITS6 = 63;
774
+ const BITS7 = 127;
775
+ /**
776
+ * @type {number}
777
+ */
778
+ const BITS31 = 0x7FFFFFFF;
779
+
780
+ /**
781
+ * Utility helpers for working with numbers.
782
+ *
783
+ * @module number
784
+ */
785
+
786
+
787
+ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
788
+
789
+ /* c8 ignore next */
790
+ const isInteger = Number.isInteger || (num => typeof num === 'number' && isFinite(num) && floor$2(num) === num);
791
+
742
792
  /**
743
793
  * @param {string} s
744
794
  * @return {string}
@@ -807,342 +857,650 @@ if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) {
807
857
  }
808
858
 
809
859
  /**
810
- * Often used conditions.
860
+ * Efficient schema-less binary encoding with support for variable length encoding.
811
861
  *
812
- * @module conditions
813
- */
814
-
815
- /**
816
- * @template T
817
- * @param {T|null|undefined} v
818
- * @return {T|null}
819
- */
820
- /* c8 ignore next */
821
- const undefinedToNull = v => v === undefined ? null : v;
822
-
823
- /* eslint-env browser */
824
-
825
- /**
826
- * Isomorphic variable storage.
862
+ * Use [lib0/encoding] with [lib0/decoding]. Every encoding function has a corresponding decoding function.
827
863
  *
828
- * Uses LocalStorage in the browser and falls back to in-memory storage.
864
+ * Encodes numbers in little-endian order (least to most significant byte order)
865
+ * and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
866
+ * which is also used in Protocol Buffers.
829
867
  *
830
- * @module storage
868
+ * ```js
869
+ * // encoding step
870
+ * const encoder = encoding.createEncoder()
871
+ * encoding.writeVarUint(encoder, 256)
872
+ * encoding.writeVarString(encoder, 'Hello world!')
873
+ * const buf = encoding.toUint8Array(encoder)
874
+ * ```
875
+ *
876
+ * ```js
877
+ * // decoding step
878
+ * const decoder = decoding.createDecoder(buf)
879
+ * decoding.readVarUint(decoder) // => 256
880
+ * decoding.readVarString(decoder) // => 'Hello world!'
881
+ * decoding.hasContent(decoder) // => false - all data is read
882
+ * ```
883
+ *
884
+ * @module encoding
831
885
  */
832
886
 
833
- /* c8 ignore start */
834
- class VarStoragePolyfill {
835
- constructor () {
836
- this.map = new Map();
837
- }
838
-
839
- /**
840
- * @param {string} key
841
- * @param {any} newValue
842
- */
843
- setItem (key, newValue) {
844
- this.map.set(key, newValue);
845
- }
846
-
847
- /**
848
- * @param {string} key
849
- */
850
- getItem (key) {
851
- return this.map.get(key)
852
- }
853
- }
854
- /* c8 ignore stop */
855
887
 
856
888
  /**
857
- * @type {any}
889
+ * A BinaryEncoder handles the encoding to an Uint8Array.
858
890
  */
859
- let _localStorage = new VarStoragePolyfill();
860
- let usePolyfill = true;
861
-
862
- /* c8 ignore start */
863
- try {
864
- // if the same-origin rule is violated, accessing localStorage might thrown an error
865
- if (typeof localStorage !== 'undefined') {
866
- _localStorage = localStorage;
867
- usePolyfill = false;
891
+ class Encoder {
892
+ constructor () {
893
+ this.cpos = 0;
894
+ this.cbuf = new Uint8Array(100);
895
+ /**
896
+ * @type {Array<Uint8Array>}
897
+ */
898
+ this.bufs = [];
868
899
  }
869
- } catch (e) { }
870
- /* c8 ignore stop */
900
+ }
871
901
 
872
902
  /**
873
- * This is basically localStorage in browser, or a polyfill in nodejs
903
+ * @function
904
+ * @return {Encoder}
874
905
  */
875
- /* c8 ignore next */
876
- const varStorage = _localStorage;
906
+ const createEncoder = () => new Encoder();
877
907
 
878
908
  /**
879
- * Utility functions for working with EcmaScript objects.
909
+ * The current length of the encoded data.
880
910
  *
881
- * @module object
911
+ * @function
912
+ * @param {Encoder} encoder
913
+ * @return {number}
882
914
  */
883
-
915
+ const length = encoder => {
916
+ let len = encoder.cpos;
917
+ for (let i = 0; i < encoder.bufs.length; i++) {
918
+ len += encoder.bufs[i].length;
919
+ }
920
+ return len
921
+ };
884
922
 
885
923
  /**
886
- * Object.assign
924
+ * Transform to Uint8Array.
925
+ *
926
+ * @function
927
+ * @param {Encoder} encoder
928
+ * @return {Uint8Array} The created ArrayBuffer.
887
929
  */
888
- const assign = Object.assign;
930
+ const toUint8Array = encoder => {
931
+ const uint8arr = new Uint8Array(length(encoder));
932
+ let curPos = 0;
933
+ for (let i = 0; i < encoder.bufs.length; i++) {
934
+ const d = encoder.bufs[i];
935
+ uint8arr.set(d, curPos);
936
+ curPos += d.length;
937
+ }
938
+ uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos);
939
+ return uint8arr
940
+ };
889
941
 
890
942
  /**
891
- * @param {Object<string,any>} obj
943
+ * Verify that it is possible to write `len` bytes wtihout checking. If
944
+ * necessary, a new Buffer with the required length is attached.
945
+ *
946
+ * @param {Encoder} encoder
947
+ * @param {number} len
892
948
  */
893
- const keys = Object.keys;
949
+ const verifyLen = (encoder, len) => {
950
+ const bufferLen = encoder.cbuf.length;
951
+ if (bufferLen - encoder.cpos < len) {
952
+ encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos));
953
+ encoder.cbuf = new Uint8Array(max$3(bufferLen, len) * 2);
954
+ encoder.cpos = 0;
955
+ }
956
+ };
894
957
 
895
958
  /**
896
- * @template V
897
- * @param {{[k:string]:V}} obj
898
- * @param {function(V,string):any} f
959
+ * Write one byte to the encoder.
960
+ *
961
+ * @function
962
+ * @param {Encoder} encoder
963
+ * @param {number} num The byte that is to be encoded.
899
964
  */
900
- const forEach$2 = (obj, f) => {
901
- for (const key in obj) {
902
- f(obj[key], key);
965
+ const write = (encoder, num) => {
966
+ const bufferLen = encoder.cbuf.length;
967
+ if (encoder.cpos === bufferLen) {
968
+ encoder.bufs.push(encoder.cbuf);
969
+ encoder.cbuf = new Uint8Array(bufferLen * 2);
970
+ encoder.cpos = 0;
903
971
  }
972
+ encoder.cbuf[encoder.cpos++] = num;
904
973
  };
905
974
 
906
975
  /**
907
- * @param {Object<string,any>} obj
908
- * @return {number}
976
+ * Write one byte as an unsigned integer.
977
+ *
978
+ * @function
979
+ * @param {Encoder} encoder
980
+ * @param {number} num The number that is to be encoded.
909
981
  */
910
- const length$1 = obj => keys(obj).length;
982
+ const writeUint8 = write;
911
983
 
912
984
  /**
913
- * @param {Object|undefined} obj
985
+ * Write a variable length unsigned integer. Max encodable integer is 2^53.
986
+ *
987
+ * @function
988
+ * @param {Encoder} encoder
989
+ * @param {number} num The number that is to be encoded.
914
990
  */
915
- const isEmpty = obj => {
916
- for (const _k in obj) {
917
- return false
991
+ const writeVarUint = (encoder, num) => {
992
+ while (num > BITS7) {
993
+ write(encoder, BIT8 | (BITS7 & num));
994
+ num = floor$2(num / 128); // shift >>> 7
918
995
  }
919
- return true
996
+ write(encoder, BITS7 & num);
920
997
  };
921
998
 
922
999
  /**
923
- * @param {Object<string,any>} obj
924
- * @param {function(any,string):boolean} f
925
- * @return {boolean}
1000
+ * Write a variable length integer.
1001
+ *
1002
+ * We use the 7th bit instead for signaling that this is a negative number.
1003
+ *
1004
+ * @function
1005
+ * @param {Encoder} encoder
1006
+ * @param {number} num The number that is to be encoded.
926
1007
  */
927
- const every = (obj, f) => {
928
- for (const key in obj) {
929
- if (!f(obj[key], key)) {
930
- return false
931
- }
1008
+ const writeVarInt = (encoder, num) => {
1009
+ const isNegative = isNegativeZero(num);
1010
+ if (isNegative) {
1011
+ num = -num;
1012
+ }
1013
+ // |- whether to continue reading |- whether is negative |- number
1014
+ write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | (BITS6 & num));
1015
+ num = floor$2(num / 64); // shift >>> 6
1016
+ // We don't need to consider the case of num === 0 so we can use a different
1017
+ // pattern here than above.
1018
+ while (num > 0) {
1019
+ write(encoder, (num > BITS7 ? BIT8 : 0) | (BITS7 & num));
1020
+ num = floor$2(num / 128); // shift >>> 7
932
1021
  }
933
- return true
934
1022
  };
935
1023
 
936
1024
  /**
937
- * Calls `Object.prototype.hasOwnProperty`.
938
- *
939
- * @param {any} obj
940
- * @param {string|symbol} key
941
- * @return {boolean}
1025
+ * A cache to store strings temporarily
942
1026
  */
943
- const hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
1027
+ const _strBuffer = new Uint8Array(30000);
1028
+ const _maxStrBSize = _strBuffer.length / 3;
944
1029
 
945
1030
  /**
946
- * @param {Object<string,any>} a
947
- * @param {Object<string,any>} b
948
- * @return {boolean}
949
- */
950
- const equalFlat = (a, b) => a === b || (length$1(a) === length$1(b) && every(a, (val, key) => (val !== undefined || hasProperty(b, key)) && b[key] === val));
951
-
952
- /**
953
- * Common functions and function call helpers.
1031
+ * Write a variable length string.
954
1032
  *
955
- * @module function
1033
+ * @function
1034
+ * @param {Encoder} encoder
1035
+ * @param {String} str The string that is to be encoded.
956
1036
  */
957
-
1037
+ const _writeVarStringNative = (encoder, str) => {
1038
+ if (str.length < _maxStrBSize) {
1039
+ // We can encode the string into the existing buffer
1040
+ /* c8 ignore next */
1041
+ const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0;
1042
+ writeVarUint(encoder, written);
1043
+ for (let i = 0; i < written; i++) {
1044
+ write(encoder, _strBuffer[i]);
1045
+ }
1046
+ } else {
1047
+ writeVarUint8Array(encoder, encodeUtf8(str));
1048
+ }
1049
+ };
958
1050
 
959
1051
  /**
960
- * Calls all functions in `fs` with args. Only throws after all functions were called.
1052
+ * Write a variable length string.
961
1053
  *
962
- * @param {Array<function>} fs
963
- * @param {Array<any>} args
1054
+ * @function
1055
+ * @param {Encoder} encoder
1056
+ * @param {String} str The string that is to be encoded.
964
1057
  */
965
- const callAll = (fs, args, i = 0) => {
966
- try {
967
- for (; i < fs.length; i++) {
968
- fs[i](...args);
969
- }
970
- } finally {
971
- if (i < fs.length) {
972
- callAll(fs, args, i + 1);
973
- }
1058
+ const _writeVarStringPolyfill = (encoder, str) => {
1059
+ const encodedString = unescape(encodeURIComponent(str));
1060
+ const len = encodedString.length;
1061
+ writeVarUint(encoder, len);
1062
+ for (let i = 0; i < len; i++) {
1063
+ write(encoder, /** @type {number} */ (encodedString.codePointAt(i)));
974
1064
  }
975
1065
  };
976
1066
 
977
1067
  /**
978
- * @template A
1068
+ * Write a variable length string.
979
1069
  *
980
- * @param {A} a
981
- * @return {A}
1070
+ * @function
1071
+ * @param {Encoder} encoder
1072
+ * @param {String} str The string that is to be encoded.
982
1073
  */
983
- const id = a => a;
1074
+ /* c8 ignore next */
1075
+ const writeVarString = (utf8TextEncoder && /** @type {any} */ (utf8TextEncoder).encodeInto) ? _writeVarStringNative : _writeVarStringPolyfill;
984
1076
 
985
1077
  /**
986
- * @template V
987
- * @template {V} OPTS
1078
+ * Append fixed-length Uint8Array to the encoder.
988
1079
  *
989
- * @param {V} value
990
- * @param {Array<OPTS>} options
1080
+ * @function
1081
+ * @param {Encoder} encoder
1082
+ * @param {Uint8Array} uint8Array
991
1083
  */
992
- // @ts-ignore
993
- const isOneOf = (value, options) => options.includes(value);
1084
+ const writeUint8Array = (encoder, uint8Array) => {
1085
+ const bufferLen = encoder.cbuf.length;
1086
+ const cpos = encoder.cpos;
1087
+ const leftCopyLen = min$2(bufferLen - cpos, uint8Array.length);
1088
+ const rightCopyLen = uint8Array.length - leftCopyLen;
1089
+ encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos);
1090
+ encoder.cpos += leftCopyLen;
1091
+ if (rightCopyLen > 0) {
1092
+ // Still something to write, write right half..
1093
+ // Append new buffer
1094
+ encoder.bufs.push(encoder.cbuf);
1095
+ // must have at least size of remaining buffer
1096
+ encoder.cbuf = new Uint8Array(max$3(bufferLen * 2, rightCopyLen));
1097
+ // copy array
1098
+ encoder.cbuf.set(uint8Array.subarray(leftCopyLen));
1099
+ encoder.cpos = rightCopyLen;
1100
+ }
1101
+ };
994
1102
 
995
1103
  /**
996
- * Isomorphic module to work access the environment (query params, env variables).
1104
+ * Append an Uint8Array to Encoder.
997
1105
  *
998
- * @module map
1106
+ * @function
1107
+ * @param {Encoder} encoder
1108
+ * @param {Uint8Array} uint8Array
999
1109
  */
1000
-
1001
-
1002
- /* c8 ignore next */
1003
- // @ts-ignore
1004
- const isNode = typeof process !== 'undefined' && process.release &&
1005
- /node|io\.js/.test(process.release.name);
1110
+ const writeVarUint8Array = (encoder, uint8Array) => {
1111
+ writeVarUint(encoder, uint8Array.byteLength);
1112
+ writeUint8Array(encoder, uint8Array);
1113
+ };
1006
1114
 
1007
1115
  /**
1008
- * @type {Map<string,string>}
1116
+ * Create an DataView of the next `len` bytes. Use it to write data after
1117
+ * calling this function.
1118
+ *
1119
+ * ```js
1120
+ * // write float32 using DataView
1121
+ * const dv = writeOnDataView(encoder, 4)
1122
+ * dv.setFloat32(0, 1.1)
1123
+ * // read float32 using DataView
1124
+ * const dv = readFromDataView(encoder, 4)
1125
+ * dv.getFloat32(0) // => 1.100000023841858 (leaving it to the reader to find out why this is the correct result)
1126
+ * ```
1127
+ *
1128
+ * @param {Encoder} encoder
1129
+ * @param {number} len
1130
+ * @return {DataView}
1009
1131
  */
1010
- let params;
1011
-
1012
- /* c8 ignore start */
1013
- const computeParams = () => {
1014
- if (params === undefined) {
1015
- if (isNode) {
1016
- params = create$5();
1017
- const pargs = process.argv;
1018
- let currParamName = null;
1019
- for (let i = 0; i < pargs.length; i++) {
1020
- const parg = pargs[i];
1021
- if (parg[0] === '-') {
1022
- if (currParamName !== null) {
1023
- params.set(currParamName, '');
1024
- }
1025
- currParamName = parg;
1026
- } else {
1027
- if (currParamName !== null) {
1028
- params.set(currParamName, parg);
1029
- currParamName = null;
1030
- }
1031
- }
1032
- }
1033
- if (currParamName !== null) {
1034
- params.set(currParamName, '');
1035
- }
1036
- // in ReactNative for example this would not be true (unless connected to the Remote Debugger)
1037
- } else if (typeof location === 'object') {
1038
- params = create$5(); // eslint-disable-next-line no-undef
1039
- (location.search || '?').slice(1).split('&').forEach((kv) => {
1040
- if (kv.length !== 0) {
1041
- const [key, value] = kv.split('=');
1042
- params.set(`--${fromCamelCase(key, '-')}`, value);
1043
- params.set(`-${fromCamelCase(key, '-')}`, value);
1044
- }
1045
- });
1046
- } else {
1047
- params = create$5();
1048
- }
1049
- }
1050
- return params
1132
+ const writeOnDataView = (encoder, len) => {
1133
+ verifyLen(encoder, len);
1134
+ const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len);
1135
+ encoder.cpos += len;
1136
+ return dview
1051
1137
  };
1052
- /* c8 ignore stop */
1053
1138
 
1054
1139
  /**
1055
- * @param {string} name
1056
- * @return {boolean}
1140
+ * @param {Encoder} encoder
1141
+ * @param {number} num
1057
1142
  */
1058
- /* c8 ignore next */
1059
- const hasParam = (name) => computeParams().has(name);
1143
+ const writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false);
1060
1144
 
1061
1145
  /**
1062
- * @param {string} name
1063
- * @return {string|null}
1146
+ * @param {Encoder} encoder
1147
+ * @param {number} num
1064
1148
  */
1065
- /* c8 ignore next 4 */
1066
- const getVariable = (name) =>
1067
- isNode
1068
- ? undefinedToNull(process.env[name.toUpperCase()])
1069
- : undefinedToNull(varStorage.getItem(name));
1149
+ const writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false);
1070
1150
 
1071
1151
  /**
1072
- * @param {string} name
1073
- * @return {boolean}
1152
+ * @param {Encoder} encoder
1153
+ * @param {bigint} num
1074
1154
  */
1075
- /* c8 ignore next 2 */
1076
- const hasConf = (name) =>
1077
- hasParam('--' + name) || getVariable(name) !== null;
1078
-
1079
- /* c8 ignore next */
1080
- hasConf('production');
1081
-
1082
- /* c8 ignore next 2 */
1083
- const forceColor = isNode &&
1084
- isOneOf(process.env.FORCE_COLOR, ['true', '1', '2']);
1085
-
1086
- /* c8 ignore start */
1087
- const supportsColor = !hasParam('no-colors') &&
1088
- (!isNode || process.stdout.isTTY || forceColor) && (
1089
- !isNode || hasParam('color') || forceColor ||
1090
- getVariable('COLORTERM') !== null ||
1091
- (getVariable('TERM') || '').includes('color')
1092
- );
1093
- /* c8 ignore stop */
1094
-
1095
- /* eslint-env browser */
1155
+ const writeBigInt64 = (encoder, num) => /** @type {any} */ (writeOnDataView(encoder, 8)).setBigInt64(0, num, false);
1096
1156
 
1157
+ const floatTestBed = new DataView(new ArrayBuffer(4));
1097
1158
  /**
1098
- * Binary data constants.
1159
+ * Check if a number can be encoded as a 32 bit float.
1099
1160
  *
1100
- * @module binary
1161
+ * @param {number} num
1162
+ * @return {boolean}
1101
1163
  */
1164
+ const isFloat32 = num => {
1165
+ floatTestBed.setFloat32(0, num);
1166
+ return floatTestBed.getFloat32(0) === num
1167
+ };
1102
1168
 
1103
1169
  /**
1104
- * n-th bit activated.
1170
+ * Encode data with efficient binary format.
1105
1171
  *
1106
- * @type {number}
1107
- */
1108
- const BIT1 = 1;
1109
- const BIT2 = 2;
1110
- const BIT3 = 4;
1111
- const BIT4 = 8;
1112
- const BIT6 = 32;
1113
- const BIT7 = 64;
1114
- const BIT8 = 128;
1115
- const BITS5 = 31;
1116
- const BITS6 = 63;
1117
- const BITS7 = 127;
1118
- /**
1119
- * @type {number}
1120
- */
1121
- const BITS31 = 0x7FFFFFFF;
1122
-
1123
- /**
1124
- * Utility helpers for working with numbers.
1172
+ * Differences to JSON:
1173
+ * • Transforms data to a binary format (not to a string)
1174
+ * Encodes undefined, NaN, and ArrayBuffer (these can't be represented in JSON)
1175
+ * Numbers are efficiently encoded either as a variable length integer, as a
1176
+ * 32 bit float, as a 64 bit float, or as a 64 bit bigint.
1125
1177
  *
1126
- * @module number
1127
- */
1128
-
1129
-
1130
- const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
1131
-
1132
- /* c8 ignore next */
1133
- const isInteger = Number.isInteger || (num => typeof num === 'number' && isFinite(num) && floor$2(num) === num);
1134
-
1135
- /**
1136
- * Error helpers.
1178
+ * Encoding table:
1137
1179
  *
1138
- * @module error
1139
- */
1140
-
1141
- /**
1142
- * @param {string} s
1143
- * @return {Error}
1144
- */
1145
- /* c8 ignore next */
1180
+ * | Data Type | Prefix | Encoding Method | Comment |
1181
+ * | ------------------- | -------- | ------------------ | ------- |
1182
+ * | undefined | 127 | | Functions, symbol, and everything that cannot be identified is encoded as undefined |
1183
+ * | null | 126 | | |
1184
+ * | integer | 125 | writeVarInt | Only encodes 32 bit signed integers |
1185
+ * | float32 | 124 | writeFloat32 | |
1186
+ * | float64 | 123 | writeFloat64 | |
1187
+ * | bigint | 122 | writeBigInt64 | |
1188
+ * | boolean (false) | 121 | | True and false are different data types so we save the following byte |
1189
+ * | boolean (true) | 120 | | - 0b01111000 so the last bit determines whether true or false |
1190
+ * | string | 119 | writeVarString | |
1191
+ * | object<string,any> | 118 | custom | Writes {length} then {length} key-value pairs |
1192
+ * | array<any> | 117 | custom | Writes {length} then {length} json values |
1193
+ * | Uint8Array | 116 | writeVarUint8Array | We use Uint8Array for any kind of binary data |
1194
+ *
1195
+ * Reasons for the decreasing prefix:
1196
+ * We need the first bit for extendability (later we may want to encode the
1197
+ * prefix with writeVarUint). The remaining 7 bits are divided as follows:
1198
+ * [0-30] the beginning of the data range is used for custom purposes
1199
+ * (defined by the function that uses this library)
1200
+ * [31-127] the end of the data range is used for data encoding by
1201
+ * lib0/encoding.js
1202
+ *
1203
+ * @param {Encoder} encoder
1204
+ * @param {undefined|null|number|bigint|boolean|string|Object<string,any>|Array<any>|Uint8Array} data
1205
+ */
1206
+ const writeAny = (encoder, data) => {
1207
+ switch (typeof data) {
1208
+ case 'string':
1209
+ // TYPE 119: STRING
1210
+ write(encoder, 119);
1211
+ writeVarString(encoder, data);
1212
+ break
1213
+ case 'number':
1214
+ if (isInteger(data) && abs$2(data) <= BITS31) {
1215
+ // TYPE 125: INTEGER
1216
+ write(encoder, 125);
1217
+ writeVarInt(encoder, data);
1218
+ } else if (isFloat32(data)) {
1219
+ // TYPE 124: FLOAT32
1220
+ write(encoder, 124);
1221
+ writeFloat32(encoder, data);
1222
+ } else {
1223
+ // TYPE 123: FLOAT64
1224
+ write(encoder, 123);
1225
+ writeFloat64(encoder, data);
1226
+ }
1227
+ break
1228
+ case 'bigint':
1229
+ // TYPE 122: BigInt
1230
+ write(encoder, 122);
1231
+ writeBigInt64(encoder, data);
1232
+ break
1233
+ case 'object':
1234
+ if (data === null) {
1235
+ // TYPE 126: null
1236
+ write(encoder, 126);
1237
+ } else if (isArray(data)) {
1238
+ // TYPE 117: Array
1239
+ write(encoder, 117);
1240
+ writeVarUint(encoder, data.length);
1241
+ for (let i = 0; i < data.length; i++) {
1242
+ writeAny(encoder, data[i]);
1243
+ }
1244
+ } else if (data instanceof Uint8Array) {
1245
+ // TYPE 116: ArrayBuffer
1246
+ write(encoder, 116);
1247
+ writeVarUint8Array(encoder, data);
1248
+ } else {
1249
+ // TYPE 118: Object
1250
+ write(encoder, 118);
1251
+ const keys = Object.keys(data);
1252
+ writeVarUint(encoder, keys.length);
1253
+ for (let i = 0; i < keys.length; i++) {
1254
+ const key = keys[i];
1255
+ writeVarString(encoder, key);
1256
+ writeAny(encoder, data[key]);
1257
+ }
1258
+ }
1259
+ break
1260
+ case 'boolean':
1261
+ // TYPE 120/121: boolean (true/false)
1262
+ write(encoder, data ? 120 : 121);
1263
+ break
1264
+ default:
1265
+ // TYPE 127: undefined
1266
+ write(encoder, 127);
1267
+ }
1268
+ };
1269
+
1270
+ /**
1271
+ * Now come a few stateful encoder that have their own classes.
1272
+ */
1273
+
1274
+ /**
1275
+ * Basic Run Length Encoder - a basic compression implementation.
1276
+ *
1277
+ * Encodes [1,1,1,7] to [1,3,7,1] (3 times 1, 1 time 7). This encoder might do more harm than good if there are a lot of values that are not repeated.
1278
+ *
1279
+ * It was originally used for image compression. Cool .. article http://csbruce.com/cbm/transactor/pdfs/trans_v7_i06.pdf
1280
+ *
1281
+ * @note T must not be null!
1282
+ *
1283
+ * @template T
1284
+ */
1285
+ class RleEncoder extends Encoder {
1286
+ /**
1287
+ * @param {function(Encoder, T):void} writer
1288
+ */
1289
+ constructor (writer) {
1290
+ super();
1291
+ /**
1292
+ * The writer
1293
+ */
1294
+ this.w = writer;
1295
+ /**
1296
+ * Current state
1297
+ * @type {T|null}
1298
+ */
1299
+ this.s = null;
1300
+ this.count = 0;
1301
+ }
1302
+
1303
+ /**
1304
+ * @param {T} v
1305
+ */
1306
+ write (v) {
1307
+ if (this.s === v) {
1308
+ this.count++;
1309
+ } else {
1310
+ if (this.count > 0) {
1311
+ // flush counter, unless this is the first value (count = 0)
1312
+ writeVarUint(this, this.count - 1); // since count is always > 0, we can decrement by one. non-standard encoding ftw
1313
+ }
1314
+ this.count = 1;
1315
+ // write first value
1316
+ this.w(this, v);
1317
+ this.s = v;
1318
+ }
1319
+ }
1320
+ }
1321
+
1322
+ /**
1323
+ * @param {UintOptRleEncoder} encoder
1324
+ */
1325
+ const flushUintOptRleEncoder = encoder => {
1326
+ if (encoder.count > 0) {
1327
+ // flush counter, unless this is the first value (count = 0)
1328
+ // case 1: just a single value. set sign to positive
1329
+ // case 2: write several values. set sign to negative to indicate that there is a length coming
1330
+ writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s);
1331
+ if (encoder.count > 1) {
1332
+ writeVarUint(encoder.encoder, encoder.count - 2); // since count is always > 1, we can decrement by one. non-standard encoding ftw
1333
+ }
1334
+ }
1335
+ };
1336
+
1337
+ /**
1338
+ * Optimized Rle encoder that does not suffer from the mentioned problem of the basic Rle encoder.
1339
+ *
1340
+ * Internally uses VarInt encoder to write unsigned integers. If the input occurs multiple times, we write
1341
+ * write it as a negative number. The UintOptRleDecoder then understands that it needs to read a count.
1342
+ *
1343
+ * Encodes [1,2,3,3,3] as [1,2,-3,3] (once 1, once 2, three times 3)
1344
+ */
1345
+ class UintOptRleEncoder {
1346
+ constructor () {
1347
+ this.encoder = new Encoder();
1348
+ /**
1349
+ * @type {number}
1350
+ */
1351
+ this.s = 0;
1352
+ this.count = 0;
1353
+ }
1354
+
1355
+ /**
1356
+ * @param {number} v
1357
+ */
1358
+ write (v) {
1359
+ if (this.s === v) {
1360
+ this.count++;
1361
+ } else {
1362
+ flushUintOptRleEncoder(this);
1363
+ this.count = 1;
1364
+ this.s = v;
1365
+ }
1366
+ }
1367
+
1368
+ /**
1369
+ * Flush the encoded state and transform this to a Uint8Array.
1370
+ *
1371
+ * Note that this should only be called once.
1372
+ */
1373
+ toUint8Array () {
1374
+ flushUintOptRleEncoder(this);
1375
+ return toUint8Array(this.encoder)
1376
+ }
1377
+ }
1378
+
1379
+ /**
1380
+ * @param {IntDiffOptRleEncoder} encoder
1381
+ */
1382
+ const flushIntDiffOptRleEncoder = encoder => {
1383
+ if (encoder.count > 0) {
1384
+ // 31 bit making up the diff | wether to write the counter
1385
+ // const encodedDiff = encoder.diff << 1 | (encoder.count === 1 ? 0 : 1)
1386
+ const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1);
1387
+ // flush counter, unless this is the first value (count = 0)
1388
+ // case 1: just a single value. set first bit to positive
1389
+ // case 2: write several values. set first bit to negative to indicate that there is a length coming
1390
+ writeVarInt(encoder.encoder, encodedDiff);
1391
+ if (encoder.count > 1) {
1392
+ writeVarUint(encoder.encoder, encoder.count - 2); // since count is always > 1, we can decrement by one. non-standard encoding ftw
1393
+ }
1394
+ }
1395
+ };
1396
+
1397
+ /**
1398
+ * A combination of the IntDiffEncoder and the UintOptRleEncoder.
1399
+ *
1400
+ * The count approach is similar to the UintDiffOptRleEncoder, but instead of using the negative bitflag, it encodes
1401
+ * in the LSB whether a count is to be read. Therefore this Encoder only supports 31 bit integers!
1402
+ *
1403
+ * Encodes [1, 2, 3, 2] as [3, 1, 6, -1] (more specifically [(1 << 1) | 1, (3 << 0) | 0, -1])
1404
+ *
1405
+ * Internally uses variable length encoding. Contrary to normal UintVar encoding, the first byte contains:
1406
+ * * 1 bit that denotes whether the next value is a count (LSB)
1407
+ * * 1 bit that denotes whether this value is negative (MSB - 1)
1408
+ * * 1 bit that denotes whether to continue reading the variable length integer (MSB)
1409
+ *
1410
+ * Therefore, only five bits remain to encode diff ranges.
1411
+ *
1412
+ * Use this Encoder only when appropriate. In most cases, this is probably a bad idea.
1413
+ */
1414
+ class IntDiffOptRleEncoder {
1415
+ constructor () {
1416
+ this.encoder = new Encoder();
1417
+ /**
1418
+ * @type {number}
1419
+ */
1420
+ this.s = 0;
1421
+ this.count = 0;
1422
+ this.diff = 0;
1423
+ }
1424
+
1425
+ /**
1426
+ * @param {number} v
1427
+ */
1428
+ write (v) {
1429
+ if (this.diff === v - this.s) {
1430
+ this.s = v;
1431
+ this.count++;
1432
+ } else {
1433
+ flushIntDiffOptRleEncoder(this);
1434
+ this.count = 1;
1435
+ this.diff = v - this.s;
1436
+ this.s = v;
1437
+ }
1438
+ }
1439
+
1440
+ /**
1441
+ * Flush the encoded state and transform this to a Uint8Array.
1442
+ *
1443
+ * Note that this should only be called once.
1444
+ */
1445
+ toUint8Array () {
1446
+ flushIntDiffOptRleEncoder(this);
1447
+ return toUint8Array(this.encoder)
1448
+ }
1449
+ }
1450
+
1451
+ /**
1452
+ * Optimized String Encoder.
1453
+ *
1454
+ * Encoding many small strings in a simple Encoder is not very efficient. The function call to decode a string takes some time and creates references that must be eventually deleted.
1455
+ * In practice, when decoding several million small strings, the GC will kick in more and more often to collect orphaned string objects (or maybe there is another reason?).
1456
+ *
1457
+ * This string encoder solves the above problem. All strings are concatenated and written as a single string using a single encoding call.
1458
+ *
1459
+ * The lengths are encoded using a UintOptRleEncoder.
1460
+ */
1461
+ class StringEncoder {
1462
+ constructor () {
1463
+ /**
1464
+ * @type {Array<string>}
1465
+ */
1466
+ this.sarr = [];
1467
+ this.s = '';
1468
+ this.lensE = new UintOptRleEncoder();
1469
+ }
1470
+
1471
+ /**
1472
+ * @param {string} string
1473
+ */
1474
+ write (string) {
1475
+ this.s += string;
1476
+ if (this.s.length > 19) {
1477
+ this.sarr.push(this.s);
1478
+ this.s = '';
1479
+ }
1480
+ this.lensE.write(string.length);
1481
+ }
1482
+
1483
+ toUint8Array () {
1484
+ const encoder = new Encoder();
1485
+ this.sarr.push(this.s);
1486
+ this.s = '';
1487
+ writeVarString(encoder, this.sarr.join(''));
1488
+ writeUint8Array(encoder, this.lensE.toUint8Array());
1489
+ return toUint8Array(encoder)
1490
+ }
1491
+ }
1492
+
1493
+ /**
1494
+ * Error helpers.
1495
+ *
1496
+ * @module error
1497
+ */
1498
+
1499
+ /**
1500
+ * @param {string} s
1501
+ * @return {Error}
1502
+ */
1503
+ /* c8 ignore next */
1146
1504
  const create$3 = s => new Error(s);
1147
1505
 
1148
1506
  /**
@@ -1244,7 +1602,7 @@ const hasContent = decoder => decoder.pos !== decoder.arr.length;
1244
1602
  * @return {Uint8Array}
1245
1603
  */
1246
1604
  const readUint8Array = (decoder, len) => {
1247
- const view = createUint8ArrayViewFromArrayBuffer(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len);
1605
+ const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len);
1248
1606
  decoder.pos += len;
1249
1607
  return view
1250
1608
  };
@@ -1576,717 +1934,418 @@ class StringDecoder {
1576
1934
  /**
1577
1935
  * @type {number}
1578
1936
  */
1579
- this.spos = 0;
1580
- }
1581
-
1582
- /**
1583
- * @return {string}
1584
- */
1585
- read () {
1586
- const end = this.spos + this.decoder.read();
1587
- const res = this.str.slice(this.spos, end);
1588
- this.spos = end;
1589
- return res
1590
- }
1591
- }
1592
-
1593
- /**
1594
- * Utility functions to work with buffers (Uint8Array).
1595
- *
1596
- * @module buffer
1597
- */
1598
-
1599
-
1600
- /**
1601
- * @param {number} len
1602
- */
1603
- const createUint8ArrayFromLen = len => new Uint8Array(len);
1604
-
1605
- /**
1606
- * Create Uint8Array with initial content from buffer
1607
- *
1608
- * @param {ArrayBuffer} buffer
1609
- * @param {number} byteOffset
1610
- * @param {number} length
1611
- */
1612
- const createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length) => new Uint8Array(buffer, byteOffset, length);
1613
-
1614
- /**
1615
- * Copy the content of an Uint8Array view to a new ArrayBuffer.
1616
- *
1617
- * @param {Uint8Array} uint8Array
1618
- * @return {Uint8Array}
1619
- */
1620
- const copyUint8Array = uint8Array => {
1621
- const newBuf = createUint8ArrayFromLen(uint8Array.byteLength);
1622
- newBuf.set(uint8Array);
1623
- return newBuf
1624
- };
1625
-
1626
- /**
1627
- * Efficient schema-less binary encoding with support for variable length encoding.
1628
- *
1629
- * Use [lib0/encoding] with [lib0/decoding]. Every encoding function has a corresponding decoding function.
1630
- *
1631
- * Encodes numbers in little-endian order (least to most significant byte order)
1632
- * and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
1633
- * which is also used in Protocol Buffers.
1634
- *
1635
- * ```js
1636
- * // encoding step
1637
- * const encoder = encoding.createEncoder()
1638
- * encoding.writeVarUint(encoder, 256)
1639
- * encoding.writeVarString(encoder, 'Hello world!')
1640
- * const buf = encoding.toUint8Array(encoder)
1641
- * ```
1642
- *
1643
- * ```js
1644
- * // decoding step
1645
- * const decoder = decoding.createDecoder(buf)
1646
- * decoding.readVarUint(decoder) // => 256
1647
- * decoding.readVarString(decoder) // => 'Hello world!'
1648
- * decoding.hasContent(decoder) // => false - all data is read
1649
- * ```
1650
- *
1651
- * @module encoding
1652
- */
1653
-
1654
-
1655
- /**
1656
- * A BinaryEncoder handles the encoding to an Uint8Array.
1657
- */
1658
- class Encoder {
1659
- constructor () {
1660
- this.cpos = 0;
1661
- this.cbuf = new Uint8Array(100);
1662
- /**
1663
- * @type {Array<Uint8Array>}
1664
- */
1665
- this.bufs = [];
1666
- }
1667
- }
1668
-
1669
- /**
1670
- * @function
1671
- * @return {Encoder}
1672
- */
1673
- const createEncoder = () => new Encoder();
1674
-
1675
- /**
1676
- * The current length of the encoded data.
1677
- *
1678
- * @function
1679
- * @param {Encoder} encoder
1680
- * @return {number}
1681
- */
1682
- const length = encoder => {
1683
- let len = encoder.cpos;
1684
- for (let i = 0; i < encoder.bufs.length; i++) {
1685
- len += encoder.bufs[i].length;
1937
+ this.spos = 0;
1686
1938
  }
1687
- return len
1688
- };
1689
1939
 
1690
- /**
1691
- * Transform to Uint8Array.
1692
- *
1693
- * @function
1694
- * @param {Encoder} encoder
1695
- * @return {Uint8Array} The created ArrayBuffer.
1696
- */
1697
- const toUint8Array = encoder => {
1698
- const uint8arr = new Uint8Array(length(encoder));
1699
- let curPos = 0;
1700
- for (let i = 0; i < encoder.bufs.length; i++) {
1701
- const d = encoder.bufs[i];
1702
- uint8arr.set(d, curPos);
1703
- curPos += d.length;
1940
+ /**
1941
+ * @return {string}
1942
+ */
1943
+ read () {
1944
+ const end = this.spos + this.decoder.read();
1945
+ const res = this.str.slice(this.spos, end);
1946
+ this.spos = end;
1947
+ return res
1704
1948
  }
1705
- uint8arr.set(createUint8ArrayViewFromArrayBuffer(encoder.cbuf.buffer, 0, encoder.cpos), curPos);
1706
- return uint8arr
1707
- };
1949
+ }
1708
1950
 
1709
- /**
1710
- * Verify that it is possible to write `len` bytes wtihout checking. If
1711
- * necessary, a new Buffer with the required length is attached.
1712
- *
1713
- * @param {Encoder} encoder
1714
- * @param {number} len
1715
- */
1716
- const verifyLen = (encoder, len) => {
1717
- const bufferLen = encoder.cbuf.length;
1718
- if (bufferLen - encoder.cpos < len) {
1719
- encoder.bufs.push(createUint8ArrayViewFromArrayBuffer(encoder.cbuf.buffer, 0, encoder.cpos));
1720
- encoder.cbuf = new Uint8Array(max$3(bufferLen, len) * 2);
1721
- encoder.cpos = 0;
1722
- }
1723
- };
1951
+ /* eslint-env browser */
1952
+
1953
+ const getRandomValues = crypto.getRandomValues.bind(crypto);
1724
1954
 
1725
1955
  /**
1726
- * Write one byte to the encoder.
1956
+ * Isomorphic module for true random numbers / buffers / uuids.
1727
1957
  *
1728
- * @function
1729
- * @param {Encoder} encoder
1730
- * @param {number} num The byte that is to be encoded.
1958
+ * Attention: falls back to Math.random if the browser does not support crypto.
1959
+ *
1960
+ * @module random
1731
1961
  */
1732
- const write = (encoder, num) => {
1733
- const bufferLen = encoder.cbuf.length;
1734
- if (encoder.cpos === bufferLen) {
1735
- encoder.bufs.push(encoder.cbuf);
1736
- encoder.cbuf = new Uint8Array(bufferLen * 2);
1737
- encoder.cpos = 0;
1738
- }
1739
- encoder.cbuf[encoder.cpos++] = num;
1740
- };
1962
+
1963
+
1964
+ const uint32 = () => getRandomValues(new Uint32Array(1))[0];
1965
+
1966
+ // @ts-ignore
1967
+ const uuidv4Template = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;
1741
1968
 
1742
1969
  /**
1743
- * Write one byte as an unsigned integer.
1744
- *
1745
- * @function
1746
- * @param {Encoder} encoder
1747
- * @param {number} num The number that is to be encoded.
1970
+ * @return {string}
1748
1971
  */
1749
- const writeUint8 = write;
1972
+ const uuidv4 = () => uuidv4Template.replace(/[018]/g, /** @param {number} c */ c =>
1973
+ (c ^ uint32() & 15 >> c / 4).toString(16)
1974
+ );
1750
1975
 
1751
1976
  /**
1752
- * Write a variable length unsigned integer. Max encodable integer is 2^53.
1977
+ * Utility helpers to work with promises.
1753
1978
  *
1754
- * @function
1755
- * @param {Encoder} encoder
1756
- * @param {number} num The number that is to be encoded.
1979
+ * @module promise
1757
1980
  */
1758
- const writeVarUint = (encoder, num) => {
1759
- while (num > BITS7) {
1760
- write(encoder, BIT8 | (BITS7 & num));
1761
- num = floor$2(num / 128); // shift >>> 7
1762
- }
1763
- write(encoder, BITS7 & num);
1764
- };
1981
+
1765
1982
 
1766
1983
  /**
1767
- * Write a variable length integer.
1768
- *
1769
- * We use the 7th bit instead for signaling that this is a negative number.
1770
- *
1771
- * @function
1772
- * @param {Encoder} encoder
1773
- * @param {number} num The number that is to be encoded.
1984
+ * @template T
1985
+ * @callback PromiseResolve
1986
+ * @param {T|PromiseLike<T>} [result]
1774
1987
  */
1775
- const writeVarInt = (encoder, num) => {
1776
- const isNegative = isNegativeZero(num);
1777
- if (isNegative) {
1778
- num = -num;
1779
- }
1780
- // |- whether to continue reading |- whether is negative |- number
1781
- write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | (BITS6 & num));
1782
- num = floor$2(num / 64); // shift >>> 6
1783
- // We don't need to consider the case of num === 0 so we can use a different
1784
- // pattern here than above.
1785
- while (num > 0) {
1786
- write(encoder, (num > BITS7 ? BIT8 : 0) | (BITS7 & num));
1787
- num = floor$2(num / 128); // shift >>> 7
1788
- }
1789
- };
1790
1988
 
1791
1989
  /**
1792
- * A cache to store strings temporarily
1990
+ * @template T
1991
+ * @param {function(PromiseResolve<T>,function(Error):void):any} f
1992
+ * @return {Promise<T>}
1793
1993
  */
1794
- const _strBuffer = new Uint8Array(30000);
1795
- const _maxStrBSize = _strBuffer.length / 3;
1994
+ const create$2 = f => /** @type {Promise<T>} */ (new Promise(f));
1796
1995
 
1797
1996
  /**
1798
- * Write a variable length string.
1997
+ * `Promise.all` wait for all promises in the array to resolve and return the result
1998
+ * @template {unknown[] | []} PS
1799
1999
  *
1800
- * @function
1801
- * @param {Encoder} encoder
1802
- * @param {String} str The string that is to be encoded.
2000
+ * @param {PS} ps
2001
+ * @return {Promise<{ -readonly [P in keyof PS]: Awaited<PS[P]> }>}
1803
2002
  */
1804
- const _writeVarStringNative = (encoder, str) => {
1805
- if (str.length < _maxStrBSize) {
1806
- // We can encode the string into the existing buffer
1807
- /* c8 ignore next */
1808
- const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0;
1809
- writeVarUint(encoder, written);
1810
- for (let i = 0; i < written; i++) {
1811
- write(encoder, _strBuffer[i]);
1812
- }
1813
- } else {
1814
- writeVarUint8Array(encoder, encodeUtf8(str));
1815
- }
1816
- };
2003
+ Promise.all.bind(Promise);
1817
2004
 
1818
2005
  /**
1819
- * Write a variable length string.
2006
+ * Often used conditions.
1820
2007
  *
1821
- * @function
1822
- * @param {Encoder} encoder
1823
- * @param {String} str The string that is to be encoded.
2008
+ * @module conditions
1824
2009
  */
1825
- const _writeVarStringPolyfill = (encoder, str) => {
1826
- const encodedString = unescape(encodeURIComponent(str));
1827
- const len = encodedString.length;
1828
- writeVarUint(encoder, len);
1829
- for (let i = 0; i < len; i++) {
1830
- write(encoder, /** @type {number} */ (encodedString.codePointAt(i)));
1831
- }
1832
- };
1833
2010
 
1834
2011
  /**
1835
- * Write a variable length string.
1836
- *
1837
- * @function
1838
- * @param {Encoder} encoder
1839
- * @param {String} str The string that is to be encoded.
2012
+ * @template T
2013
+ * @param {T|null|undefined} v
2014
+ * @return {T|null}
1840
2015
  */
1841
2016
  /* c8 ignore next */
1842
- const writeVarString = (utf8TextEncoder && /** @type {any} */ (utf8TextEncoder).encodeInto) ? _writeVarStringNative : _writeVarStringPolyfill;
2017
+ const undefinedToNull = v => v === undefined ? null : v;
2018
+
2019
+ /* eslint-env browser */
1843
2020
 
1844
2021
  /**
1845
- * Append fixed-length Uint8Array to the encoder.
2022
+ * Isomorphic variable storage.
1846
2023
  *
1847
- * @function
1848
- * @param {Encoder} encoder
1849
- * @param {Uint8Array} uint8Array
2024
+ * Uses LocalStorage in the browser and falls back to in-memory storage.
2025
+ *
2026
+ * @module storage
1850
2027
  */
1851
- const writeUint8Array = (encoder, uint8Array) => {
1852
- const bufferLen = encoder.cbuf.length;
1853
- const cpos = encoder.cpos;
1854
- const leftCopyLen = min$2(bufferLen - cpos, uint8Array.length);
1855
- const rightCopyLen = uint8Array.length - leftCopyLen;
1856
- encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos);
1857
- encoder.cpos += leftCopyLen;
1858
- if (rightCopyLen > 0) {
1859
- // Still something to write, write right half..
1860
- // Append new buffer
1861
- encoder.bufs.push(encoder.cbuf);
1862
- // must have at least size of remaining buffer
1863
- encoder.cbuf = new Uint8Array(max$3(bufferLen * 2, rightCopyLen));
1864
- // copy array
1865
- encoder.cbuf.set(uint8Array.subarray(leftCopyLen));
1866
- encoder.cpos = rightCopyLen;
2028
+
2029
+ /* c8 ignore start */
2030
+ class VarStoragePolyfill {
2031
+ constructor () {
2032
+ this.map = new Map();
1867
2033
  }
1868
- };
1869
2034
 
1870
- /**
1871
- * Append an Uint8Array to Encoder.
1872
- *
1873
- * @function
1874
- * @param {Encoder} encoder
1875
- * @param {Uint8Array} uint8Array
1876
- */
1877
- const writeVarUint8Array = (encoder, uint8Array) => {
1878
- writeVarUint(encoder, uint8Array.byteLength);
1879
- writeUint8Array(encoder, uint8Array);
1880
- };
2035
+ /**
2036
+ * @param {string} key
2037
+ * @param {any} newValue
2038
+ */
2039
+ setItem (key, newValue) {
2040
+ this.map.set(key, newValue);
2041
+ }
2042
+
2043
+ /**
2044
+ * @param {string} key
2045
+ */
2046
+ getItem (key) {
2047
+ return this.map.get(key)
2048
+ }
2049
+ }
2050
+ /* c8 ignore stop */
1881
2051
 
1882
2052
  /**
1883
- * Create an DataView of the next `len` bytes. Use it to write data after
1884
- * calling this function.
1885
- *
1886
- * ```js
1887
- * // write float32 using DataView
1888
- * const dv = writeOnDataView(encoder, 4)
1889
- * dv.setFloat32(0, 1.1)
1890
- * // read float32 using DataView
1891
- * const dv = readFromDataView(encoder, 4)
1892
- * dv.getFloat32(0) // => 1.100000023841858 (leaving it to the reader to find out why this is the correct result)
1893
- * ```
1894
- *
1895
- * @param {Encoder} encoder
1896
- * @param {number} len
1897
- * @return {DataView}
2053
+ * @type {any}
1898
2054
  */
1899
- const writeOnDataView = (encoder, len) => {
1900
- verifyLen(encoder, len);
1901
- const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len);
1902
- encoder.cpos += len;
1903
- return dview
1904
- };
2055
+ let _localStorage = new VarStoragePolyfill();
2056
+ let usePolyfill = true;
2057
+
2058
+ /* c8 ignore start */
2059
+ try {
2060
+ // if the same-origin rule is violated, accessing localStorage might thrown an error
2061
+ if (typeof localStorage !== 'undefined' && localStorage) {
2062
+ _localStorage = localStorage;
2063
+ usePolyfill = false;
2064
+ }
2065
+ } catch (e) { }
2066
+ /* c8 ignore stop */
1905
2067
 
1906
2068
  /**
1907
- * @param {Encoder} encoder
1908
- * @param {number} num
2069
+ * This is basically localStorage in browser, or a polyfill in nodejs
1909
2070
  */
1910
- const writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false);
2071
+ /* c8 ignore next */
2072
+ const varStorage = _localStorage;
1911
2073
 
1912
2074
  /**
1913
- * @param {Encoder} encoder
1914
- * @param {number} num
2075
+ * Utility functions for working with EcmaScript objects.
2076
+ *
2077
+ * @module object
1915
2078
  */
1916
- const writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false);
2079
+
1917
2080
 
1918
2081
  /**
1919
- * @param {Encoder} encoder
1920
- * @param {bigint} num
2082
+ * Object.assign
1921
2083
  */
1922
- const writeBigInt64 = (encoder, num) => /** @type {any} */ (writeOnDataView(encoder, 8)).setBigInt64(0, num, false);
2084
+ const assign = Object.assign;
1923
2085
 
1924
- const floatTestBed = new DataView(new ArrayBuffer(4));
1925
2086
  /**
1926
- * Check if a number can be encoded as a 32 bit float.
1927
- *
1928
- * @param {number} num
1929
- * @return {boolean}
2087
+ * @param {Object<string,any>} obj
1930
2088
  */
1931
- const isFloat32 = num => {
1932
- floatTestBed.setFloat32(0, num);
1933
- return floatTestBed.getFloat32(0) === num
1934
- };
2089
+ const keys = Object.keys;
1935
2090
 
1936
2091
  /**
1937
- * Encode data with efficient binary format.
1938
- *
1939
- * Differences to JSON:
1940
- * • Transforms data to a binary format (not to a string)
1941
- * • Encodes undefined, NaN, and ArrayBuffer (these can't be represented in JSON)
1942
- * • Numbers are efficiently encoded either as a variable length integer, as a
1943
- * 32 bit float, as a 64 bit float, or as a 64 bit bigint.
1944
- *
1945
- * Encoding table:
1946
- *
1947
- * | Data Type | Prefix | Encoding Method | Comment |
1948
- * | ------------------- | -------- | ------------------ | ------- |
1949
- * | undefined | 127 | | Functions, symbol, and everything that cannot be identified is encoded as undefined |
1950
- * | null | 126 | | |
1951
- * | integer | 125 | writeVarInt | Only encodes 32 bit signed integers |
1952
- * | float32 | 124 | writeFloat32 | |
1953
- * | float64 | 123 | writeFloat64 | |
1954
- * | bigint | 122 | writeBigInt64 | |
1955
- * | boolean (false) | 121 | | True and false are different data types so we save the following byte |
1956
- * | boolean (true) | 120 | | - 0b01111000 so the last bit determines whether true or false |
1957
- * | string | 119 | writeVarString | |
1958
- * | object<string,any> | 118 | custom | Writes {length} then {length} key-value pairs |
1959
- * | array<any> | 117 | custom | Writes {length} then {length} json values |
1960
- * | Uint8Array | 116 | writeVarUint8Array | We use Uint8Array for any kind of binary data |
1961
- *
1962
- * Reasons for the decreasing prefix:
1963
- * We need the first bit for extendability (later we may want to encode the
1964
- * prefix with writeVarUint). The remaining 7 bits are divided as follows:
1965
- * [0-30] the beginning of the data range is used for custom purposes
1966
- * (defined by the function that uses this library)
1967
- * [31-127] the end of the data range is used for data encoding by
1968
- * lib0/encoding.js
1969
- *
1970
- * @param {Encoder} encoder
1971
- * @param {undefined|null|number|bigint|boolean|string|Object<string,any>|Array<any>|Uint8Array} data
2092
+ * @template V
2093
+ * @param {{[k:string]:V}} obj
2094
+ * @param {function(V,string):any} f
1972
2095
  */
1973
- const writeAny = (encoder, data) => {
1974
- switch (typeof data) {
1975
- case 'string':
1976
- // TYPE 119: STRING
1977
- write(encoder, 119);
1978
- writeVarString(encoder, data);
1979
- break
1980
- case 'number':
1981
- if (isInteger(data) && abs$2(data) <= BITS31) {
1982
- // TYPE 125: INTEGER
1983
- write(encoder, 125);
1984
- writeVarInt(encoder, data);
1985
- } else if (isFloat32(data)) {
1986
- // TYPE 124: FLOAT32
1987
- write(encoder, 124);
1988
- writeFloat32(encoder, data);
1989
- } else {
1990
- // TYPE 123: FLOAT64
1991
- write(encoder, 123);
1992
- writeFloat64(encoder, data);
1993
- }
1994
- break
1995
- case 'bigint':
1996
- // TYPE 122: BigInt
1997
- write(encoder, 122);
1998
- writeBigInt64(encoder, data);
1999
- break
2000
- case 'object':
2001
- if (data === null) {
2002
- // TYPE 126: null
2003
- write(encoder, 126);
2004
- } else if (isArray(data)) {
2005
- // TYPE 117: Array
2006
- write(encoder, 117);
2007
- writeVarUint(encoder, data.length);
2008
- for (let i = 0; i < data.length; i++) {
2009
- writeAny(encoder, data[i]);
2010
- }
2011
- } else if (data instanceof Uint8Array) {
2012
- // TYPE 116: ArrayBuffer
2013
- write(encoder, 116);
2014
- writeVarUint8Array(encoder, data);
2015
- } else {
2016
- // TYPE 118: Object
2017
- write(encoder, 118);
2018
- const keys = Object.keys(data);
2019
- writeVarUint(encoder, keys.length);
2020
- for (let i = 0; i < keys.length; i++) {
2021
- const key = keys[i];
2022
- writeVarString(encoder, key);
2023
- writeAny(encoder, data[key]);
2024
- }
2025
- }
2026
- break
2027
- case 'boolean':
2028
- // TYPE 120/121: boolean (true/false)
2029
- write(encoder, data ? 120 : 121);
2030
- break
2031
- default:
2032
- // TYPE 127: undefined
2033
- write(encoder, 127);
2096
+ const forEach$2 = (obj, f) => {
2097
+ for (const key in obj) {
2098
+ f(obj[key], key);
2034
2099
  }
2035
2100
  };
2036
2101
 
2037
2102
  /**
2038
- * Now come a few stateful encoder that have their own classes.
2103
+ * @param {Object<string,any>} obj
2104
+ * @return {number}
2039
2105
  */
2106
+ const size = obj => keys(obj).length;
2040
2107
 
2041
2108
  /**
2042
- * Basic Run Length Encoder - a basic compression implementation.
2043
- *
2044
- * Encodes [1,1,1,7] to [1,3,7,1] (3 times 1, 1 time 7). This encoder might do more harm than good if there are a lot of values that are not repeated.
2045
- *
2046
- * It was originally used for image compression. Cool .. article http://csbruce.com/cbm/transactor/pdfs/trans_v7_i06.pdf
2047
- *
2048
- * @note T must not be null!
2049
- *
2050
- * @template T
2109
+ * @param {Object|null|undefined} obj
2051
2110
  */
2052
- class RleEncoder extends Encoder {
2053
- /**
2054
- * @param {function(Encoder, T):void} writer
2055
- */
2056
- constructor (writer) {
2057
- super();
2058
- /**
2059
- * The writer
2060
- */
2061
- this.w = writer;
2062
- /**
2063
- * Current state
2064
- * @type {T|null}
2065
- */
2066
- this.s = null;
2067
- this.count = 0;
2068
- }
2069
-
2070
- /**
2071
- * @param {T} v
2072
- */
2073
- write (v) {
2074
- if (this.s === v) {
2075
- this.count++;
2076
- } else {
2077
- if (this.count > 0) {
2078
- // flush counter, unless this is the first value (count = 0)
2079
- writeVarUint(this, this.count - 1); // since count is always > 0, we can decrement by one. non-standard encoding ftw
2080
- }
2081
- this.count = 1;
2082
- // write first value
2083
- this.w(this, v);
2084
- this.s = v;
2085
- }
2111
+ const isEmpty = obj => {
2112
+ // eslint-disable-next-line no-unreachable-loop
2113
+ for (const _k in obj) {
2114
+ return false
2086
2115
  }
2087
- }
2116
+ return true
2117
+ };
2088
2118
 
2089
2119
  /**
2090
- * @param {UintOptRleEncoder} encoder
2120
+ * @param {Object<string,any>} obj
2121
+ * @param {function(any,string):boolean} f
2122
+ * @return {boolean}
2091
2123
  */
2092
- const flushUintOptRleEncoder = encoder => {
2093
- if (encoder.count > 0) {
2094
- // flush counter, unless this is the first value (count = 0)
2095
- // case 1: just a single value. set sign to positive
2096
- // case 2: write several values. set sign to negative to indicate that there is a length coming
2097
- writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s);
2098
- if (encoder.count > 1) {
2099
- writeVarUint(encoder.encoder, encoder.count - 2); // since count is always > 1, we can decrement by one. non-standard encoding ftw
2124
+ const every = (obj, f) => {
2125
+ for (const key in obj) {
2126
+ if (!f(obj[key], key)) {
2127
+ return false
2100
2128
  }
2101
2129
  }
2130
+ return true
2102
2131
  };
2103
2132
 
2104
2133
  /**
2105
- * Optimized Rle encoder that does not suffer from the mentioned problem of the basic Rle encoder.
2106
- *
2107
- * Internally uses VarInt encoder to write unsigned integers. If the input occurs multiple times, we write
2108
- * write it as a negative number. The UintOptRleDecoder then understands that it needs to read a count.
2134
+ * Calls `Object.prototype.hasOwnProperty`.
2109
2135
  *
2110
- * Encodes [1,2,3,3,3] as [1,2,-3,3] (once 1, once 2, three times 3)
2136
+ * @param {any} obj
2137
+ * @param {string|symbol} key
2138
+ * @return {boolean}
2111
2139
  */
2112
- class UintOptRleEncoder {
2113
- constructor () {
2114
- this.encoder = new Encoder();
2115
- /**
2116
- * @type {number}
2117
- */
2118
- this.s = 0;
2119
- this.count = 0;
2120
- }
2140
+ const hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
2121
2141
 
2122
- /**
2123
- * @param {number} v
2124
- */
2125
- write (v) {
2126
- if (this.s === v) {
2127
- this.count++;
2128
- } else {
2129
- flushUintOptRleEncoder(this);
2130
- this.count = 1;
2131
- this.s = v;
2142
+ /**
2143
+ * @param {Object<string,any>} a
2144
+ * @param {Object<string,any>} b
2145
+ * @return {boolean}
2146
+ */
2147
+ const equalFlat = (a, b) => a === b || (size(a) === size(b) && every(a, (val, key) => (val !== undefined || hasProperty(b, key)) && b[key] === val));
2148
+
2149
+ /**
2150
+ * Make an object immutable. This hurts performance and is usually not needed if you perform good
2151
+ * coding practices.
2152
+ */
2153
+ const freeze = Object.freeze;
2154
+
2155
+ /**
2156
+ * Make an object and all its children immutable.
2157
+ * This *really* hurts performance and is usually not needed if you perform good coding practices.
2158
+ *
2159
+ * @template {any} T
2160
+ * @param {T} o
2161
+ * @return {Readonly<T>}
2162
+ */
2163
+ const deepFreeze = (o) => {
2164
+ for (const key in o) {
2165
+ const c = o[key];
2166
+ if (typeof c === 'object' || typeof c === 'function') {
2167
+ deepFreeze(o[key]);
2132
2168
  }
2133
2169
  }
2170
+ return freeze(o)
2171
+ };
2172
+
2173
+ /**
2174
+ * Common functions and function call helpers.
2175
+ *
2176
+ * @module function
2177
+ */
2134
2178
 
2135
- toUint8Array () {
2136
- flushUintOptRleEncoder(this);
2137
- return toUint8Array(this.encoder)
2138
- }
2139
- }
2140
2179
 
2141
2180
  /**
2142
- * @param {IntDiffOptRleEncoder} encoder
2181
+ * Calls all functions in `fs` with args. Only throws after all functions were called.
2182
+ *
2183
+ * @param {Array<function>} fs
2184
+ * @param {Array<any>} args
2143
2185
  */
2144
- const flushIntDiffOptRleEncoder = encoder => {
2145
- if (encoder.count > 0) {
2146
- // 31 bit making up the diff | wether to write the counter
2147
- // const encodedDiff = encoder.diff << 1 | (encoder.count === 1 ? 0 : 1)
2148
- const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1);
2149
- // flush counter, unless this is the first value (count = 0)
2150
- // case 1: just a single value. set first bit to positive
2151
- // case 2: write several values. set first bit to negative to indicate that there is a length coming
2152
- writeVarInt(encoder.encoder, encodedDiff);
2153
- if (encoder.count > 1) {
2154
- writeVarUint(encoder.encoder, encoder.count - 2); // since count is always > 1, we can decrement by one. non-standard encoding ftw
2186
+ const callAll = (fs, args, i = 0) => {
2187
+ try {
2188
+ for (; i < fs.length; i++) {
2189
+ fs[i](...args);
2190
+ }
2191
+ } finally {
2192
+ if (i < fs.length) {
2193
+ callAll(fs, args, i + 1);
2155
2194
  }
2156
2195
  }
2157
2196
  };
2158
2197
 
2159
2198
  /**
2160
- * A combination of the IntDiffEncoder and the UintOptRleEncoder.
2161
- *
2162
- * The count approach is similar to the UintDiffOptRleEncoder, but instead of using the negative bitflag, it encodes
2163
- * in the LSB whether a count is to be read. Therefore this Encoder only supports 31 bit integers!
2164
- *
2165
- * Encodes [1, 2, 3, 2] as [3, 1, 6, -1] (more specifically [(1 << 1) | 1, (3 << 0) | 0, -1])
2199
+ * @template A
2166
2200
  *
2167
- * Internally uses variable length encoding. Contrary to normal UintVar encoding, the first byte contains:
2168
- * * 1 bit that denotes whether the next value is a count (LSB)
2169
- * * 1 bit that denotes whether this value is negative (MSB - 1)
2170
- * * 1 bit that denotes whether to continue reading the variable length integer (MSB)
2201
+ * @param {A} a
2202
+ * @return {A}
2203
+ */
2204
+ const id = a => a;
2205
+
2206
+ /**
2207
+ * @template V
2208
+ * @template {V} OPTS
2171
2209
  *
2172
- * Therefore, only five bits remain to encode diff ranges.
2210
+ * @param {V} value
2211
+ * @param {Array<OPTS>} options
2212
+ */
2213
+ // @ts-ignore
2214
+ const isOneOf = (value, options) => options.includes(value);
2215
+
2216
+ /**
2217
+ * Isomorphic module to work access the environment (query params, env variables).
2173
2218
  *
2174
- * Use this Encoder only when appropriate. In most cases, this is probably a bad idea.
2219
+ * @module environment
2175
2220
  */
2176
- class IntDiffOptRleEncoder {
2177
- constructor () {
2178
- this.encoder = new Encoder();
2179
- /**
2180
- * @type {number}
2181
- */
2182
- this.s = 0;
2183
- this.count = 0;
2184
- this.diff = 0;
2185
- }
2186
2221
 
2187
- /**
2188
- * @param {number} v
2189
- */
2190
- write (v) {
2191
- if (this.diff === v - this.s) {
2192
- this.s = v;
2193
- this.count++;
2194
- } else {
2195
- flushIntDiffOptRleEncoder(this);
2196
- this.count = 1;
2197
- this.diff = v - this.s;
2198
- this.s = v;
2199
- }
2200
- }
2201
2222
 
2202
- toUint8Array () {
2203
- flushIntDiffOptRleEncoder(this);
2204
- return toUint8Array(this.encoder)
2205
- }
2206
- }
2223
+ /* c8 ignore next 2 */
2224
+ // @ts-ignore
2225
+ const isNode = typeof process !== 'undefined' && process.release && /node|io\.js/.test(process.release.name) && Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
2207
2226
 
2208
2227
  /**
2209
- * Optimized String Encoder.
2210
- *
2211
- * Encoding many small strings in a simple Encoder is not very efficient. The function call to decode a string takes some time and creates references that must be eventually deleted.
2212
- * In practice, when decoding several million small strings, the GC will kick in more and more often to collect orphaned string objects (or maybe there is another reason?).
2213
- *
2214
- * This string encoder solves the above problem. All strings are concatenated and written as a single string using a single encoding call.
2215
- *
2216
- * The lengths are encoded using a UintOptRleEncoder.
2228
+ * @type {Map<string,string>}
2217
2229
  */
2218
- class StringEncoder {
2219
- constructor () {
2220
- /**
2221
- * @type {Array<string>}
2222
- */
2223
- this.sarr = [];
2224
- this.s = '';
2225
- this.lensE = new UintOptRleEncoder();
2226
- }
2230
+ let params;
2227
2231
 
2228
- /**
2229
- * @param {string} string
2230
- */
2231
- write (string) {
2232
- this.s += string;
2233
- if (this.s.length > 19) {
2234
- this.sarr.push(this.s);
2235
- this.s = '';
2232
+ /* c8 ignore start */
2233
+ const computeParams = () => {
2234
+ if (params === undefined) {
2235
+ if (isNode) {
2236
+ params = create$5();
2237
+ const pargs = process.argv;
2238
+ let currParamName = null;
2239
+ for (let i = 0; i < pargs.length; i++) {
2240
+ const parg = pargs[i];
2241
+ if (parg[0] === '-') {
2242
+ if (currParamName !== null) {
2243
+ params.set(currParamName, '');
2244
+ }
2245
+ currParamName = parg;
2246
+ } else {
2247
+ if (currParamName !== null) {
2248
+ params.set(currParamName, parg);
2249
+ currParamName = null;
2250
+ }
2251
+ }
2252
+ }
2253
+ if (currParamName !== null) {
2254
+ params.set(currParamName, '');
2255
+ }
2256
+ // in ReactNative for example this would not be true (unless connected to the Remote Debugger)
2257
+ } else if (typeof location === 'object') {
2258
+ params = create$5(); // eslint-disable-next-line no-undef
2259
+ (location.search || '?').slice(1).split('&').forEach((kv) => {
2260
+ if (kv.length !== 0) {
2261
+ const [key, value] = kv.split('=');
2262
+ params.set(`--${fromCamelCase(key, '-')}`, value);
2263
+ params.set(`-${fromCamelCase(key, '-')}`, value);
2264
+ }
2265
+ });
2266
+ } else {
2267
+ params = create$5();
2236
2268
  }
2237
- this.lensE.write(string.length);
2238
2269
  }
2270
+ return params
2271
+ };
2272
+ /* c8 ignore stop */
2239
2273
 
2240
- toUint8Array () {
2241
- const encoder = new Encoder();
2242
- this.sarr.push(this.s);
2243
- this.s = '';
2244
- writeVarString(encoder, this.sarr.join(''));
2245
- writeUint8Array(encoder, this.lensE.toUint8Array());
2246
- return toUint8Array(encoder)
2247
- }
2248
- }
2274
+ /**
2275
+ * @param {string} name
2276
+ * @return {boolean}
2277
+ */
2278
+ /* c8 ignore next */
2279
+ const hasParam = (name) => computeParams().has(name);
2249
2280
 
2250
- /* eslint-env browser */
2281
+ /**
2282
+ * @param {string} name
2283
+ * @return {string|null}
2284
+ */
2285
+ /* c8 ignore next 4 */
2286
+ const getVariable = (name) =>
2287
+ isNode
2288
+ ? undefinedToNull(process.env[name.toUpperCase().replaceAll('-', '_')])
2289
+ : undefinedToNull(varStorage.getItem(name));
2251
2290
 
2252
- const getRandomValues = crypto.getRandomValues.bind(crypto);
2291
+ /**
2292
+ * @param {string} name
2293
+ * @return {boolean}
2294
+ */
2295
+ /* c8 ignore next 2 */
2296
+ const hasConf = (name) =>
2297
+ hasParam('--' + name) || getVariable(name) !== null;
2253
2298
 
2254
- const uint32 = () => getRandomValues(new Uint32Array(1))[0];
2299
+ /* c8 ignore next */
2300
+ hasConf('production');
2255
2301
 
2256
- // @ts-ignore
2257
- const uuidv4Template = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;
2258
- const uuidv4 = () => uuidv4Template.replace(/[018]/g, /** @param {number} c */ c =>
2259
- (c ^ uint32() & 15 >> c / 4).toString(16)
2260
- );
2302
+ /* c8 ignore next 2 */
2303
+ const forceColor = isNode &&
2304
+ isOneOf(process.env.FORCE_COLOR, ['true', '1', '2']);
2261
2305
 
2306
+ /* c8 ignore start */
2262
2307
  /**
2263
- * Utility helpers to work with promises.
2308
+ * Color is enabled by default if the terminal supports it.
2264
2309
  *
2265
- * @module promise
2310
+ * Explicitly enable color using `--color` parameter
2311
+ * Disable color using `--no-color` parameter or using `NO_COLOR=1` environment variable.
2312
+ * `FORCE_COLOR=1` enables color and takes precedence over all.
2266
2313
  */
2267
-
2314
+ const supportsColor = forceColor || (
2315
+ !hasParam('--no-colors') && // @todo deprecate --no-colors
2316
+ !hasConf('no-color') &&
2317
+ (!isNode || process.stdout.isTTY) && (
2318
+ !isNode ||
2319
+ hasParam('--color') ||
2320
+ getVariable('COLORTERM') !== null ||
2321
+ (getVariable('TERM') || '').includes('color')
2322
+ )
2323
+ );
2324
+ /* c8 ignore stop */
2268
2325
 
2269
2326
  /**
2270
- * @template T
2271
- * @callback PromiseResolve
2272
- * @param {T|PromiseLike<T>} [result]
2327
+ * Utility functions to work with buffers (Uint8Array).
2328
+ *
2329
+ * @module buffer
2273
2330
  */
2274
2331
 
2332
+
2275
2333
  /**
2276
- * @template T
2277
- * @param {function(PromiseResolve<T>,function(Error):void):any} f
2278
- * @return {Promise<T>}
2334
+ * @param {number} len
2279
2335
  */
2280
- const create$2 = f => /** @type {Promise<T>} */ (new Promise(f));
2336
+ const createUint8ArrayFromLen = len => new Uint8Array(len);
2281
2337
 
2282
2338
  /**
2283
- * `Promise.all` wait for all promises in the array to resolve and return the result
2284
- * @template {unknown[] | []} PS
2339
+ * Copy the content of an Uint8Array view to a new ArrayBuffer.
2285
2340
  *
2286
- * @param {PS} ps
2287
- * @return {Promise<{ -readonly [P in keyof PS]: Awaited<PS[P]> }>}
2341
+ * @param {Uint8Array} uint8Array
2342
+ * @return {Uint8Array}
2288
2343
  */
2289
- Promise.all.bind(Promise);
2344
+ const copyUint8Array = uint8Array => {
2345
+ const newBuf = createUint8ArrayFromLen(uint8Array.byteLength);
2346
+ newBuf.set(uint8Array);
2347
+ return newBuf
2348
+ };
2290
2349
 
2291
2350
  /**
2292
2351
  * Working with value pairs.
@@ -2336,8 +2395,6 @@ const mapToStyleString = m => map(m, (value, key) => `${key}:${value};`).join(''
2336
2395
 
2337
2396
  /**
2338
2397
  * Return fresh symbol.
2339
- *
2340
- * @return {Symbol}
2341
2398
  */
2342
2399
  const create = Symbol;
2343
2400
 
@@ -2353,17 +2410,36 @@ const UNCOLOR = create();
2353
2410
 
2354
2411
  /* c8 ignore start */
2355
2412
  /**
2356
- * @param {Array<string|Symbol|Object|number>} args
2357
- * @return {Array<string|object|number>}
2413
+ * @param {Array<undefined|string|Symbol|Object|number|function():any>} args
2414
+ * @return {Array<string|object|number|undefined>}
2358
2415
  */
2359
2416
  const computeNoColorLoggingArgs = args => {
2417
+ if (args.length === 1 && args[0]?.constructor === Function) {
2418
+ args = /** @type {Array<string|Symbol|Object|number>} */ (/** @type {[function]} */ (args)[0]());
2419
+ }
2420
+ const strBuilder = [];
2360
2421
  const logArgs = [];
2361
2422
  // try with formatting until we find something unsupported
2362
2423
  let i = 0;
2363
2424
  for (; i < args.length; i++) {
2364
2425
  const arg = args[i];
2365
- if (arg.constructor === String || arg.constructor === Number) ; else if (arg.constructor === Object) {
2366
- logArgs.push(JSON.stringify(arg));
2426
+ if (arg === undefined) {
2427
+ break
2428
+ } else if (arg.constructor === String || arg.constructor === Number) {
2429
+ strBuilder.push(arg);
2430
+ } else if (arg.constructor === Object) {
2431
+ break
2432
+ }
2433
+ }
2434
+ if (i > 0) {
2435
+ // create logArgs with what we have so far
2436
+ logArgs.push(strBuilder.join(''));
2437
+ }
2438
+ // append the rest
2439
+ for (; i < args.length; i++) {
2440
+ const arg = args[i];
2441
+ if (!(arg instanceof Symbol)) {
2442
+ logArgs.push(arg);
2367
2443
  }
2368
2444
  }
2369
2445
  return logArgs
@@ -2393,11 +2469,14 @@ const _browserStyleMap = {
2393
2469
  };
2394
2470
 
2395
2471
  /**
2396
- * @param {Array<string|Symbol|Object|number>} args
2472
+ * @param {Array<string|Symbol|Object|number|function():any>} args
2397
2473
  * @return {Array<string|object|number>}
2398
2474
  */
2399
2475
  /* c8 ignore start */
2400
2476
  const computeBrowserLoggingArgs = (args) => {
2477
+ if (args.length === 1 && args[0]?.constructor === Function) {
2478
+ args = /** @type {Array<string|Symbol|Object|number>} */ (/** @type {[function]} */ (args)[0]());
2479
+ }
2401
2480
  const strBuilder = [];
2402
2481
  const styles = [];
2403
2482
  const currentStyle = create$5();
@@ -2414,6 +2493,9 @@ const computeBrowserLoggingArgs = (args) => {
2414
2493
  if (style !== undefined) {
2415
2494
  currentStyle.set(style.left, style.right);
2416
2495
  } else {
2496
+ if (arg === undefined) {
2497
+ break
2498
+ }
2417
2499
  if (arg.constructor === String || arg.constructor === Number) {
2418
2500
  const style = mapToStyleString(currentStyle);
2419
2501
  if (i > 0 || style.length > 0) {
@@ -2452,9 +2534,19 @@ const computeLoggingArgs = supportsColor
2452
2534
  /**
2453
2535
  * @param {Array<string|Symbol|Object|number>} args
2454
2536
  */
2455
- const print = (...args) => {
2456
- console.log(...computeLoggingArgs(args));
2457
- /* c8 ignore next */
2537
+ const print = (...args) => {
2538
+ console.log(...computeLoggingArgs(args));
2539
+ /* c8 ignore next */
2540
+ vconsoles.forEach((vc) => vc.print(args));
2541
+ };
2542
+
2543
+ /* c8 ignore start */
2544
+ /**
2545
+ * @param {Array<string|Symbol|Object|number>} args
2546
+ */
2547
+ const warn = (...args) => {
2548
+ console.warn(...computeLoggingArgs(args));
2549
+ args.unshift(ORANGE);
2458
2550
  vconsoles.forEach((vc) => vc.print(args));
2459
2551
  };
2460
2552
 
@@ -2551,9 +2643,12 @@ class DeleteSet {
2551
2643
  const iterateDeletedStructs = (transaction, ds, f) =>
2552
2644
  ds.clients.forEach((deletes, clientid) => {
2553
2645
  const structs = /** @type {Array<GC|Item>} */ (transaction.doc.store.clients.get(clientid));
2554
- for (let i = 0; i < deletes.length; i++) {
2555
- const del = deletes[i];
2556
- iterateStructs(transaction, structs, del.clock, del.len, f);
2646
+ if (structs != null) {
2647
+ const lastStruct = structs[structs.length - 1];
2648
+ const clockState = lastStruct.id.clock + lastStruct.length;
2649
+ for (let i = 0, del = deletes[i]; i < deletes.length && del.clock < clockState; del = deletes[++i]) {
2650
+ iterateStructs(transaction, structs, del.clock, del.len, f);
2651
+ }
2557
2652
  }
2558
2653
  });
2559
2654
 
@@ -2825,6 +2920,7 @@ const readAndApplyDeleteSet = (decoder, transaction, store) => {
2825
2920
  * @module Y
2826
2921
  */
2827
2922
 
2923
+
2828
2924
  const generateNewClientId = uint32;
2829
2925
 
2830
2926
  /**
@@ -2838,11 +2934,27 @@ const generateNewClientId = uint32;
2838
2934
  * @property {boolean} [DocOpts.shouldLoad] Whether the document should be synced by the provider now. This is toggled to true when you call ydoc.load()
2839
2935
  */
2840
2936
 
2937
+ /**
2938
+ * @typedef {Object} DocEvents
2939
+ * @property {function(Doc):void} DocEvents.destroy
2940
+ * @property {function(Doc):void} DocEvents.load
2941
+ * @property {function(boolean, Doc):void} DocEvents.sync
2942
+ * @property {function(Uint8Array, any, Doc, Transaction):void} DocEvents.update
2943
+ * @property {function(Uint8Array, any, Doc, Transaction):void} DocEvents.updateV2
2944
+ * @property {function(Doc):void} DocEvents.beforeAllTransactions
2945
+ * @property {function(Transaction, Doc):void} DocEvents.beforeTransaction
2946
+ * @property {function(Transaction, Doc):void} DocEvents.beforeObserverCalls
2947
+ * @property {function(Transaction, Doc):void} DocEvents.afterTransaction
2948
+ * @property {function(Transaction, Doc):void} DocEvents.afterTransactionCleanup
2949
+ * @property {function(Doc, Array<Transaction>):void} DocEvents.afterAllTransactions
2950
+ * @property {function({ loaded: Set<Doc>, added: Set<Doc>, removed: Set<Doc> }, Doc, Transaction):void} DocEvents.subdocs
2951
+ */
2952
+
2841
2953
  /**
2842
2954
  * A Yjs instance handles the state of shared data.
2843
- * @extends Observable<string>
2955
+ * @extends ObservableV2<DocEvents>
2844
2956
  */
2845
- class Doc extends Observable {
2957
+ class Doc extends ObservableV2 {
2846
2958
  /**
2847
2959
  * @param {DocOpts} opts configuration
2848
2960
  */
@@ -2893,8 +3005,9 @@ class Doc extends Observable {
2893
3005
  * lost (with false as a parameter).
2894
3006
  */
2895
3007
  this.isSynced = false;
3008
+ this.isDestroyed = false;
2896
3009
  /**
2897
- * Promise that resolves once the document has been loaded from a presistence provider.
3010
+ * Promise that resolves once the document has been loaded from a persistence provider.
2898
3011
  */
2899
3012
  this.whenLoaded = create$2(resolve => {
2900
3013
  this.on('load', () => {
@@ -2919,8 +3032,8 @@ class Doc extends Observable {
2919
3032
  this.whenSynced = provideSyncedPromise();
2920
3033
  }
2921
3034
  this.isSynced = isSynced === undefined || isSynced === true;
2922
- if (!this.isLoaded) {
2923
- this.emit('load', []);
3035
+ if (this.isSynced && !this.isLoaded) {
3036
+ this.emit('load', [this]);
2924
3037
  }
2925
3038
  });
2926
3039
  /**
@@ -2941,7 +3054,7 @@ class Doc extends Observable {
2941
3054
  load () {
2942
3055
  const item = this._item;
2943
3056
  if (item !== null && !this.shouldLoad) {
2944
- transact(/** @type {any} */ (item.parent).doc, transaction => {
3057
+ transact$1(/** @type {any} */ (item.parent).doc, transaction => {
2945
3058
  transaction.subdocsLoaded.add(this);
2946
3059
  }, null, true);
2947
3060
  }
@@ -2970,36 +3083,37 @@ class Doc extends Observable {
2970
3083
  * @public
2971
3084
  */
2972
3085
  transact (f, origin = null) {
2973
- return transact(this, f, origin)
3086
+ return transact$1(this, f, origin)
2974
3087
  }
2975
3088
 
2976
3089
  /**
2977
3090
  * Define a shared data type.
2978
3091
  *
2979
- * Multiple calls of `y.get(name, TypeConstructor)` yield the same result
3092
+ * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result
2980
3093
  * and do not overwrite each other. I.e.
2981
- * `y.define(name, Y.Array) === y.define(name, Y.Array)`
3094
+ * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)`
2982
3095
  *
2983
- * After this method is called, the type is also available on `y.share.get(name)`.
3096
+ * After this method is called, the type is also available on `ydoc.share.get(name)`.
2984
3097
  *
2985
3098
  * *Best Practices:*
2986
- * Define all types right after the Yjs instance is created and store them in a separate object.
3099
+ * Define all types right after the Y.Doc instance is created and store them in a separate object.
2987
3100
  * Also use the typed methods `getText(name)`, `getArray(name)`, ..
2988
3101
  *
3102
+ * @template {typeof AbstractType<any>} Type
2989
3103
  * @example
2990
- * const y = new Y(..)
3104
+ * const ydoc = new Y.Doc(..)
2991
3105
  * const appState = {
2992
- * document: y.getText('document')
2993
- * comments: y.getArray('comments')
3106
+ * document: ydoc.getText('document')
3107
+ * comments: ydoc.getArray('comments')
2994
3108
  * }
2995
3109
  *
2996
3110
  * @param {string} name
2997
- * @param {Function} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ...
2998
- * @return {AbstractType<any>} The created type. Constructed with TypeConstructor
3111
+ * @param {Type} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ...
3112
+ * @return {InstanceType<Type>} The created type. Constructed with TypeConstructor
2999
3113
  *
3000
3114
  * @public
3001
3115
  */
3002
- get (name, TypeConstructor = AbstractType) {
3116
+ get (name, TypeConstructor = /** @type {any} */ (AbstractType)) {
3003
3117
  const type = setIfUndefined(this.share, name, () => {
3004
3118
  // @ts-ignore
3005
3119
  const t = new TypeConstructor();
@@ -3025,12 +3139,12 @@ class Doc extends Observable {
3025
3139
  t._length = type._length;
3026
3140
  this.share.set(name, t);
3027
3141
  t._integrate(this, null);
3028
- return t
3142
+ return /** @type {InstanceType<Type>} */ (t)
3029
3143
  } else {
3030
3144
  throw new Error(`Type with the name ${name} has already been defined with a different constructor`)
3031
3145
  }
3032
3146
  }
3033
- return type
3147
+ return /** @type {InstanceType<Type>} */ (type)
3034
3148
  }
3035
3149
 
3036
3150
  /**
@@ -3041,8 +3155,7 @@ class Doc extends Observable {
3041
3155
  * @public
3042
3156
  */
3043
3157
  getArray (name = '') {
3044
- // @ts-ignore
3045
- return this.get(name, YArray)
3158
+ return /** @type {YArray<T>} */ (this.get(name, YArray))
3046
3159
  }
3047
3160
 
3048
3161
  /**
@@ -3052,7 +3165,6 @@ class Doc extends Observable {
3052
3165
  * @public
3053
3166
  */
3054
3167
  getText (name = '') {
3055
- // @ts-ignore
3056
3168
  return this.get(name, YText)
3057
3169
  }
3058
3170
 
@@ -3064,8 +3176,17 @@ class Doc extends Observable {
3064
3176
  * @public
3065
3177
  */
3066
3178
  getMap (name = '') {
3067
- // @ts-ignore
3068
- return this.get(name, YMap)
3179
+ return /** @type {YMap<T>} */ (this.get(name, YMap))
3180
+ }
3181
+
3182
+ /**
3183
+ * @param {string} [name]
3184
+ * @return {YXmlElement}
3185
+ *
3186
+ * @public
3187
+ */
3188
+ getXmlElement (name = '') {
3189
+ return /** @type {YXmlElement<{[key:string]:string}>} */ (this.get(name, YXmlElement))
3069
3190
  }
3070
3191
 
3071
3192
  /**
@@ -3075,7 +3196,6 @@ class Doc extends Observable {
3075
3196
  * @public
3076
3197
  */
3077
3198
  getXmlFragment (name = '') {
3078
- // @ts-ignore
3079
3199
  return this.get(name, YXmlFragment)
3080
3200
  }
3081
3201
 
@@ -3104,6 +3224,7 @@ class Doc extends Observable {
3104
3224
  * Emit `destroy` event and unregister all event handlers.
3105
3225
  */
3106
3226
  destroy () {
3227
+ this.isDestroyed = true;
3107
3228
  from(this.subdocs).forEach(subdoc => subdoc.destroy());
3108
3229
  const item = this._item;
3109
3230
  if (item !== null) {
@@ -3111,7 +3232,7 @@ class Doc extends Observable {
3111
3232
  const content = /** @type {ContentDoc} */ (item.content);
3112
3233
  content.doc = new Doc({ guid: this.guid, ...content.opts, shouldLoad: false });
3113
3234
  content.doc._item = item;
3114
- transact(/** @type {any} */ (item).parent.doc, transaction => {
3235
+ transact$1(/** @type {any} */ (item).parent.doc, transaction => {
3115
3236
  const doc = content.doc;
3116
3237
  if (!item.deleted) {
3117
3238
  transaction.subdocsAdded.add(doc);
@@ -3119,26 +3240,11 @@ class Doc extends Observable {
3119
3240
  transaction.subdocsRemoved.add(this);
3120
3241
  }, null, true);
3121
3242
  }
3122
- this.emit('destroyed', [true]);
3243
+ // @ts-ignore
3244
+ this.emit('destroyed', [true]); // DEPRECATED!
3123
3245
  this.emit('destroy', [this]);
3124
3246
  super.destroy();
3125
3247
  }
3126
-
3127
- /**
3128
- * @param {string} eventName
3129
- * @param {function(...any):any} f
3130
- */
3131
- on (eventName, f) {
3132
- super.on(eventName, f);
3133
- }
3134
-
3135
- /**
3136
- * @param {string} eventName
3137
- * @param {function} f
3138
- */
3139
- off (eventName, f) {
3140
- super.off(eventName, f);
3141
- }
3142
3248
  }
3143
3249
 
3144
3250
  class DSDecoderV1 {
@@ -3579,7 +3685,7 @@ class UpdateEncoderV2 extends DSEncoderV2 {
3579
3685
  */
3580
3686
  this.keyMap = new Map();
3581
3687
  /**
3582
- * Refers to the next uniqe key-identifier to me used.
3688
+ * Refers to the next unique key-identifier to me used.
3583
3689
  * See writeKey method for more information.
3584
3690
  *
3585
3691
  * @type {number}
@@ -3731,6 +3837,23 @@ class UpdateEncoderV2 extends DSEncoderV2 {
3731
3837
  }
3732
3838
  }
3733
3839
 
3840
+ /**
3841
+ * @module encoding
3842
+ */
3843
+ /*
3844
+ * We use the first five bits in the info flag for determining the type of the struct.
3845
+ *
3846
+ * 0: GC
3847
+ * 1: Item with Deleted content
3848
+ * 2: Item with JSON content
3849
+ * 3: Item with Binary content
3850
+ * 4: Item with String content
3851
+ * 5: Item with Embed content (for richtext content)
3852
+ * 6: Item with Format content (a formatting marker for richtext content)
3853
+ * 7: Item with Type
3854
+ */
3855
+
3856
+
3734
3857
  /**
3735
3858
  * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
3736
3859
  * @param {Array<GC|Item>} structs All structs by `client`
@@ -3839,7 +3962,7 @@ const readClientsStructRefs = (decoder, doc) => {
3839
3962
  // @type {string|null}
3840
3963
  const struct = new Item(
3841
3964
  createID(client, clock),
3842
- null, // leftd
3965
+ null, // left
3843
3966
  (info & BIT8) === BIT8 ? decoder.readLeftID() : null, // origin
3844
3967
  null, // right
3845
3968
  (info & BIT7) === BIT7 ? decoder.readRightID() : null, // right origin
@@ -3863,7 +3986,7 @@ const readClientsStructRefs = (decoder, doc) => {
3863
3986
 
3864
3987
  const struct = new Item(
3865
3988
  createID(client, clock),
3866
- null, // leftd
3989
+ null, // left
3867
3990
  origin, // origin
3868
3991
  null, // right
3869
3992
  rightOrigin, // right origin
@@ -3896,7 +4019,7 @@ const readClientsStructRefs = (decoder, doc) => {
3896
4019
  * then we start emptying the stack.
3897
4020
  *
3898
4021
  * It is not possible to have circles: i.e. struct1 (from client1) depends on struct2 (from client2)
3899
- * depends on struct3 (from client1). Therefore the max stack size is eqaul to `structReaders.length`.
4022
+ * depends on struct3 (from client1). Therefore the max stack size is equal to `structReaders.length`.
3900
4023
  *
3901
4024
  * This method is implemented in a way so that we can resume computation if this update
3902
4025
  * causally depends on another update.
@@ -3935,7 +4058,7 @@ const integrateStructs = (transaction, store, clientsStructRefs) => {
3935
4058
  return nextStructsTarget
3936
4059
  };
3937
4060
  let curStructsTarget = getNextStructTarget();
3938
- if (curStructsTarget === null && stack.length === 0) {
4061
+ if (curStructsTarget === null) {
3939
4062
  return null
3940
4063
  }
3941
4064
 
@@ -3964,14 +4087,14 @@ const integrateStructs = (transaction, store, clientsStructRefs) => {
3964
4087
  const addStackToRestSS = () => {
3965
4088
  for (const item of stack) {
3966
4089
  const client = item.id.client;
3967
- const unapplicableItems = clientsStructRefs.get(client);
3968
- if (unapplicableItems) {
4090
+ const inapplicableItems = clientsStructRefs.get(client);
4091
+ if (inapplicableItems) {
3969
4092
  // decrement because we weren't able to apply previous operation
3970
- unapplicableItems.i--;
3971
- restStructs.clients.set(client, unapplicableItems.refs.slice(unapplicableItems.i));
4093
+ inapplicableItems.i--;
4094
+ restStructs.clients.set(client, inapplicableItems.refs.slice(inapplicableItems.i));
3972
4095
  clientsStructRefs.delete(client);
3973
- unapplicableItems.i = 0;
3974
- unapplicableItems.refs = [];
4096
+ inapplicableItems.i = 0;
4097
+ inapplicableItems.refs = [];
3975
4098
  } else {
3976
4099
  // item was the last item on clientsStructRefs and the field was already cleared. Add item to restStructs and continue
3977
4100
  restStructs.clients.set(client, [item]);
@@ -4055,7 +4178,7 @@ const writeStructsFromTransaction = (encoder, transaction) => writeClientsStruct
4055
4178
  /**
4056
4179
  * Read and apply a document update.
4057
4180
  *
4058
- * This function has the same effect as `applyUpdate` but accepts an decoder.
4181
+ * This function has the same effect as `applyUpdate` but accepts a decoder.
4059
4182
  *
4060
4183
  * @param {decoding.Decoder} decoder
4061
4184
  * @param {Doc} ydoc
@@ -4065,7 +4188,7 @@ const writeStructsFromTransaction = (encoder, transaction) => writeClientsStruct
4065
4188
  * @function
4066
4189
  */
4067
4190
  const readUpdateV2 = (decoder, ydoc, transactionOrigin, structDecoder = new UpdateDecoderV2(decoder)) =>
4068
- transact(ydoc, transaction => {
4191
+ transact$1(ydoc, transaction => {
4069
4192
  // force that transaction.local is set to non-local
4070
4193
  transaction.local = false;
4071
4194
  let retry = false;
@@ -4670,7 +4793,8 @@ const iterateStructs = (transaction, structs, clockStart, len, f) => {
4670
4793
  * possible. Here is an example to illustrate the advantages of bundling:
4671
4794
  *
4672
4795
  * @example
4673
- * const map = y.define('map', YMap)
4796
+ * const ydoc = new Y.Doc()
4797
+ * const map = ydoc.getMap('map')
4674
4798
  * // Log content when change is triggered
4675
4799
  * map.observe(() => {
4676
4800
  * console.log('change triggered')
@@ -4679,7 +4803,7 @@ const iterateStructs = (transaction, structs, clockStart, len, f) => {
4679
4803
  * map.set('a', 0) // => "change triggered"
4680
4804
  * map.set('b', 0) // => "change triggered"
4681
4805
  * // When put in a transaction, it will trigger the log after the transaction:
4682
- * y.transact(() => {
4806
+ * ydoc.transact(() => {
4683
4807
  * map.set('a', 1)
4684
4808
  * map.set('b', 1)
4685
4809
  * }) // => "change triggered"
@@ -4855,7 +4979,7 @@ const tryGcDeleteSet = (ds, store, gcFilter) => {
4855
4979
  */
4856
4980
  const tryMergeDeleteSet = (ds, store) => {
4857
4981
  // try to merge deleted / gc'd items
4858
- // merge from right to left for better efficiecy and so we don't miss any merge targets
4982
+ // merge from right to left for better efficiency and so we don't miss any merge targets
4859
4983
  ds.clients.forEach((deleteItems, client) => {
4860
4984
  const structs = /** @type {Array<GC|Item>} */ (store.clients.get(client));
4861
4985
  for (let di = deleteItems.length - 1; di >= 0; di--) {
@@ -5025,7 +5149,7 @@ const cleanupTransactions = (transactionCleanups, i) => {
5025
5149
  *
5026
5150
  * @function
5027
5151
  */
5028
- const transact = (doc, f, origin = null, local = true) => {
5152
+ const transact$1 = (doc, f, origin = null, local = true) => {
5029
5153
  const transactionCleanups = doc._transactionCleanups;
5030
5154
  let initialCall = false;
5031
5155
  /**
@@ -5720,8 +5844,8 @@ const getPathTo = (parent, child) => {
5720
5844
  let i = 0;
5721
5845
  let c = /** @type {AbstractType<any>} */ (child._item.parent)._start;
5722
5846
  while (c !== child._item && c !== null) {
5723
- if (!c.deleted) {
5724
- i++;
5847
+ if (!c.deleted && c.countable) {
5848
+ i += c.length;
5725
5849
  }
5726
5850
  c = c.right;
5727
5851
  }
@@ -5732,6 +5856,11 @@ const getPathTo = (parent, child) => {
5732
5856
  return path
5733
5857
  };
5734
5858
 
5859
+ /**
5860
+ * https://docs.yjs.dev/getting-started/working-with-shared-types#caveats
5861
+ */
5862
+ const warnPrematureAccess = () => { warn('Invalid access: Add Yjs type to a document before reading data.'); };
5863
+
5735
5864
  const maxSearchMarker = 80;
5736
5865
 
5737
5866
  /**
@@ -5863,11 +5992,11 @@ const findMarker = (yarray, index) => {
5863
5992
  // }
5864
5993
  // }
5865
5994
  // if (marker) {
5866
- // if (window.lengthes == null) {
5867
- // window.lengthes = []
5868
- // window.getLengthes = () => window.lengthes.sort((a, b) => a - b)
5995
+ // if (window.lengths == null) {
5996
+ // window.lengths = []
5997
+ // window.getLengths = () => window.lengths.sort((a, b) => a - b)
5869
5998
  // }
5870
- // window.lengthes.push(marker.index - pindex)
5999
+ // window.lengths.push(marker.index - pindex)
5871
6000
  // console.log('distance', marker.index - pindex, 'len', p && p.parent.length)
5872
6001
  // }
5873
6002
  if (marker !== null && abs$2(marker.index - pindex) < /** @type {YText|YArray<any>} */ (p.parent).length / maxSearchMarker) {
@@ -6014,6 +6143,10 @@ class AbstractType {
6014
6143
  }
6015
6144
 
6016
6145
  /**
6146
+ * Makes a copy of this data type that can be included somewhere else.
6147
+ *
6148
+ * Note that the content is only readable _after_ it has been included somewhere in the Ydoc.
6149
+ *
6017
6150
  * @return {AbstractType<EventType>}
6018
6151
  */
6019
6152
  clone () {
@@ -6102,6 +6235,7 @@ class AbstractType {
6102
6235
  * @function
6103
6236
  */
6104
6237
  const typeListSlice = (type, start, end) => {
6238
+ type.doc ?? warnPrematureAccess();
6105
6239
  if (start < 0) {
6106
6240
  start = type._length + start;
6107
6241
  }
@@ -6137,6 +6271,7 @@ const typeListSlice = (type, start, end) => {
6137
6271
  * @function
6138
6272
  */
6139
6273
  const typeListToArray = type => {
6274
+ type.doc ?? warnPrematureAccess();
6140
6275
  const cs = [];
6141
6276
  let n = type._start;
6142
6277
  while (n !== null) {
@@ -6152,7 +6287,7 @@ const typeListToArray = type => {
6152
6287
  };
6153
6288
 
6154
6289
  /**
6155
- * Executes a provided function on once on overy element of this YArray.
6290
+ * Executes a provided function on once on every element of this YArray.
6156
6291
  *
6157
6292
  * @param {AbstractType<any>} type
6158
6293
  * @param {function(any,number,any):void} f A function to execute on every element of this YArray.
@@ -6163,6 +6298,7 @@ const typeListToArray = type => {
6163
6298
  const typeListForEach = (type, f) => {
6164
6299
  let index = 0;
6165
6300
  let n = type._start;
6301
+ type.doc ?? warnPrematureAccess();
6166
6302
  while (n !== null) {
6167
6303
  if (n.countable && !n.deleted) {
6168
6304
  const c = n.content.getContent();
@@ -6252,6 +6388,7 @@ const typeListCreateIterator = type => {
6252
6388
  * @function
6253
6389
  */
6254
6390
  const typeListGet = (type, index) => {
6391
+ type.doc ?? warnPrematureAccess();
6255
6392
  const marker = findMarker(type, index);
6256
6393
  let n = type._start;
6257
6394
  if (marker !== null) {
@@ -6332,7 +6469,7 @@ const typeListInsertGenericsAfter = (transaction, parent, referenceItem, content
6332
6469
  packJsonContent();
6333
6470
  };
6334
6471
 
6335
- const lengthExceeded = create$3('Length exceeded!');
6472
+ const lengthExceeded = () => create$3('Length exceeded!');
6336
6473
 
6337
6474
  /**
6338
6475
  * @param {Transaction} transaction
@@ -6345,7 +6482,7 @@ const lengthExceeded = create$3('Length exceeded!');
6345
6482
  */
6346
6483
  const typeListInsertGenerics = (transaction, parent, index, content) => {
6347
6484
  if (index > parent._length) {
6348
- throw lengthExceeded
6485
+ throw lengthExceeded()
6349
6486
  }
6350
6487
  if (index === 0) {
6351
6488
  if (parent._searchMarker) {
@@ -6386,7 +6523,7 @@ const typeListInsertGenerics = (transaction, parent, index, content) => {
6386
6523
 
6387
6524
  /**
6388
6525
  * Pushing content is special as we generally want to push after the last item. So we don't have to update
6389
- * the serach marker.
6526
+ * the search marker.
6390
6527
  *
6391
6528
  * @param {Transaction} transaction
6392
6529
  * @param {AbstractType<any>} parent
@@ -6447,7 +6584,7 @@ const typeListDelete = (transaction, parent, index, length) => {
6447
6584
  n = n.right;
6448
6585
  }
6449
6586
  if (length > 0) {
6450
- throw lengthExceeded
6587
+ throw lengthExceeded()
6451
6588
  }
6452
6589
  if (parent._searchMarker) {
6453
6590
  updateMarkerChanges(parent._searchMarker, startIndex, -startLength + length /* in case we remove the above exception */);
@@ -6492,6 +6629,8 @@ const typeMapSet = (transaction, parent, key, value) => {
6492
6629
  case Boolean:
6493
6630
  case Array:
6494
6631
  case String:
6632
+ case Date:
6633
+ case BigInt:
6495
6634
  content = new ContentAny([value]);
6496
6635
  break
6497
6636
  case Uint8Array:
@@ -6520,6 +6659,7 @@ const typeMapSet = (transaction, parent, key, value) => {
6520
6659
  * @function
6521
6660
  */
6522
6661
  const typeMapGet = (parent, key) => {
6662
+ parent.doc ?? warnPrematureAccess();
6523
6663
  const val = parent._map.get(key);
6524
6664
  return val !== undefined && !val.deleted ? val.content.getContent()[val.length - 1] : undefined
6525
6665
  };
@@ -6536,6 +6676,7 @@ const typeMapGetAll = (parent) => {
6536
6676
  * @type {Object<string,any>}
6537
6677
  */
6538
6678
  const res = {};
6679
+ parent.doc ?? warnPrematureAccess();
6539
6680
  parent._map.forEach((value, key) => {
6540
6681
  if (!value.deleted) {
6541
6682
  res[key] = value.content.getContent()[value.length - 1];
@@ -6553,38 +6694,62 @@ const typeMapGetAll = (parent) => {
6553
6694
  * @function
6554
6695
  */
6555
6696
  const typeMapHas = (parent, key) => {
6697
+ parent.doc ?? warnPrematureAccess();
6556
6698
  const val = parent._map.get(key);
6557
6699
  return val !== undefined && !val.deleted
6558
6700
  };
6559
6701
 
6560
6702
  /**
6561
- * @param {Map<string,Item>} map
6703
+ * @param {AbstractType<any>} parent
6704
+ * @param {Snapshot} snapshot
6705
+ * @return {Object<string,Object<string,any>|number|null|Array<any>|string|Uint8Array|AbstractType<any>|undefined>}
6706
+ *
6707
+ * @private
6708
+ * @function
6709
+ */
6710
+ const typeMapGetAllSnapshot = (parent, snapshot) => {
6711
+ /**
6712
+ * @type {Object<string,any>}
6713
+ */
6714
+ const res = {};
6715
+ parent._map.forEach((value, key) => {
6716
+ /**
6717
+ * @type {Item|null}
6718
+ */
6719
+ let v = value;
6720
+ while (v !== null && (!snapshot.sv.has(v.id.client) || v.id.clock >= (snapshot.sv.get(v.id.client) || 0))) {
6721
+ v = v.left;
6722
+ }
6723
+ if (v !== null && isVisible(v, snapshot)) {
6724
+ res[key] = v.content.getContent()[v.length - 1];
6725
+ }
6726
+ });
6727
+ return res
6728
+ };
6729
+
6730
+ /**
6731
+ * @param {AbstractType<any> & { _map: Map<string, Item> }} type
6562
6732
  * @return {IterableIterator<Array<any>>}
6563
6733
  *
6564
6734
  * @private
6565
6735
  * @function
6566
6736
  */
6567
- const createMapIterator = map => iteratorFilter(map.entries(), /** @param {any} entry */ entry => !entry[1].deleted);
6737
+ const createMapIterator = type => {
6738
+ type.doc ?? warnPrematureAccess();
6739
+ return iteratorFilter(type._map.entries(), /** @param {any} entry */ entry => !entry[1].deleted)
6740
+ };
6568
6741
 
6569
6742
  /**
6570
6743
  * @module YArray
6571
6744
  */
6572
6745
 
6746
+
6573
6747
  /**
6574
6748
  * Event that describes the changes on a YArray
6575
6749
  * @template T
6576
6750
  * @extends YEvent<YArray<T>>
6577
6751
  */
6578
- class YArrayEvent extends YEvent {
6579
- /**
6580
- * @param {YArray<T>} yarray The changed type
6581
- * @param {Transaction} transaction The transaction object
6582
- */
6583
- constructor (yarray, transaction) {
6584
- super(yarray, transaction);
6585
- this._transaction = transaction;
6586
- }
6587
- }
6752
+ class YArrayEvent extends YEvent {}
6588
6753
 
6589
6754
  /**
6590
6755
  * A shared Array implementation.
@@ -6645,6 +6810,10 @@ class YArray extends AbstractType {
6645
6810
  }
6646
6811
 
6647
6812
  /**
6813
+ * Makes a copy of this data type that can be included somewhere else.
6814
+ *
6815
+ * Note that the content is only readable _after_ it has been included somewhere in the Ydoc.
6816
+ *
6648
6817
  * @return {YArray<T>}
6649
6818
  */
6650
6819
  clone () {
@@ -6659,7 +6828,8 @@ class YArray extends AbstractType {
6659
6828
  }
6660
6829
 
6661
6830
  get length () {
6662
- return this._prelimContent === null ? this._length : this._prelimContent.length
6831
+ this.doc ?? warnPrematureAccess();
6832
+ return this._length
6663
6833
  }
6664
6834
 
6665
6835
  /**
@@ -6691,7 +6861,7 @@ class YArray extends AbstractType {
6691
6861
  */
6692
6862
  insert (index, content) {
6693
6863
  if (this.doc !== null) {
6694
- transact(this.doc, transaction => {
6864
+ transact$1(this.doc, transaction => {
6695
6865
  typeListInsertGenerics(transaction, this, index, /** @type {any} */ (content));
6696
6866
  });
6697
6867
  } else {
@@ -6708,7 +6878,7 @@ class YArray extends AbstractType {
6708
6878
  */
6709
6879
  push (content) {
6710
6880
  if (this.doc !== null) {
6711
- transact(this.doc, transaction => {
6881
+ transact$1(this.doc, transaction => {
6712
6882
  typeListPushGenerics(transaction, this, /** @type {any} */ (content));
6713
6883
  });
6714
6884
  } else {
@@ -6717,9 +6887,9 @@ class YArray extends AbstractType {
6717
6887
  }
6718
6888
 
6719
6889
  /**
6720
- * Preppends content to this YArray.
6890
+ * Prepends content to this YArray.
6721
6891
  *
6722
- * @param {Array<T>} content Array of content to preppend.
6892
+ * @param {Array<T>} content Array of content to prepend.
6723
6893
  */
6724
6894
  unshift (content) {
6725
6895
  this.insert(0, content);
@@ -6733,7 +6903,7 @@ class YArray extends AbstractType {
6733
6903
  */
6734
6904
  delete (index, length = 1) {
6735
6905
  if (this.doc !== null) {
6736
- transact(this.doc, transaction => {
6906
+ transact$1(this.doc, transaction => {
6737
6907
  typeListDelete(transaction, this, index, length);
6738
6908
  });
6739
6909
  } else {
@@ -6761,7 +6931,8 @@ class YArray extends AbstractType {
6761
6931
  }
6762
6932
 
6763
6933
  /**
6764
- * Transforms this YArray to a JavaScript Array.
6934
+ * Returns a portion of this YArray into a JavaScript Array selected
6935
+ * from start to end (end not included).
6765
6936
  *
6766
6937
  * @param {number} [start]
6767
6938
  * @param {number} [end]
@@ -6794,7 +6965,7 @@ class YArray extends AbstractType {
6794
6965
  }
6795
6966
 
6796
6967
  /**
6797
- * Executes a provided function once on overy element of this YArray.
6968
+ * Executes a provided function once on every element of this YArray.
6798
6969
  *
6799
6970
  * @param {function(T,number,YArray<T>):void} f A function to execute on every element of this YArray.
6800
6971
  */
@@ -6825,6 +6996,11 @@ class YArray extends AbstractType {
6825
6996
  */
6826
6997
  const readYArray = _decoder => new YArray();
6827
6998
 
6999
+ /**
7000
+ * @module YMap
7001
+ */
7002
+
7003
+
6828
7004
  /**
6829
7005
  * @template T
6830
7006
  * @extends YEvent<YMap<T>>
@@ -6847,7 +7023,7 @@ class YMapEvent extends YEvent {
6847
7023
  * A shared Map implementation.
6848
7024
  *
6849
7025
  * @extends AbstractType<YMapEvent<MapType>>
6850
- * @implements {Iterable<MapType>}
7026
+ * @implements {Iterable<[string, MapType]>}
6851
7027
  */
6852
7028
  class YMap extends AbstractType {
6853
7029
  /**
@@ -6895,6 +7071,10 @@ class YMap extends AbstractType {
6895
7071
  }
6896
7072
 
6897
7073
  /**
7074
+ * Makes a copy of this data type that can be included somewhere else.
7075
+ *
7076
+ * Note that the content is only readable _after_ it has been included somewhere in the Ydoc.
7077
+ *
6898
7078
  * @return {YMap<MapType>}
6899
7079
  */
6900
7080
  clone () {
@@ -6924,6 +7104,7 @@ class YMap extends AbstractType {
6924
7104
  * @return {Object<string,any>}
6925
7105
  */
6926
7106
  toJSON () {
7107
+ this.doc ?? warnPrematureAccess();
6927
7108
  /**
6928
7109
  * @type {Object<string,MapType>}
6929
7110
  */
@@ -6943,7 +7124,7 @@ class YMap extends AbstractType {
6943
7124
  * @return {number}
6944
7125
  */
6945
7126
  get size () {
6946
- return [...createMapIterator(this._map)].length
7127
+ return [...createMapIterator(this)].length
6947
7128
  }
6948
7129
 
6949
7130
  /**
@@ -6952,25 +7133,25 @@ class YMap extends AbstractType {
6952
7133
  * @return {IterableIterator<string>}
6953
7134
  */
6954
7135
  keys () {
6955
- return iteratorMap(createMapIterator(this._map), /** @param {any} v */ v => v[0])
7136
+ return iteratorMap(createMapIterator(this), /** @param {any} v */ v => v[0])
6956
7137
  }
6957
7138
 
6958
7139
  /**
6959
7140
  * Returns the values for each element in the YMap Type.
6960
7141
  *
6961
- * @return {IterableIterator<any>}
7142
+ * @return {IterableIterator<MapType>}
6962
7143
  */
6963
7144
  values () {
6964
- return iteratorMap(createMapIterator(this._map), /** @param {any} v */ v => v[1].content.getContent()[v[1].length - 1])
7145
+ return iteratorMap(createMapIterator(this), /** @param {any} v */ v => v[1].content.getContent()[v[1].length - 1])
6965
7146
  }
6966
7147
 
6967
7148
  /**
6968
7149
  * Returns an Iterator of [key, value] pairs
6969
7150
  *
6970
- * @return {IterableIterator<any>}
7151
+ * @return {IterableIterator<[string, MapType]>}
6971
7152
  */
6972
7153
  entries () {
6973
- return iteratorMap(createMapIterator(this._map), /** @param {any} v */ v => [v[0], v[1].content.getContent()[v[1].length - 1]])
7154
+ return iteratorMap(createMapIterator(this), /** @param {any} v */ v => /** @type {any} */ ([v[0], v[1].content.getContent()[v[1].length - 1]]))
6974
7155
  }
6975
7156
 
6976
7157
  /**
@@ -6979,6 +7160,7 @@ class YMap extends AbstractType {
6979
7160
  * @param {function(MapType,string,YMap<MapType>):void} f A function to execute on every element of this YArray.
6980
7161
  */
6981
7162
  forEach (f) {
7163
+ this.doc ?? warnPrematureAccess();
6982
7164
  this._map.forEach((item, key) => {
6983
7165
  if (!item.deleted) {
6984
7166
  f(item.content.getContent()[item.length - 1], key, this);
@@ -6989,7 +7171,7 @@ class YMap extends AbstractType {
6989
7171
  /**
6990
7172
  * Returns an Iterator of [key, value] pairs
6991
7173
  *
6992
- * @return {IterableIterator<any>}
7174
+ * @return {IterableIterator<[string, MapType]>}
6993
7175
  */
6994
7176
  [Symbol.iterator] () {
6995
7177
  return this.entries()
@@ -7002,7 +7184,7 @@ class YMap extends AbstractType {
7002
7184
  */
7003
7185
  delete (key) {
7004
7186
  if (this.doc !== null) {
7005
- transact(this.doc, transaction => {
7187
+ transact$1(this.doc, transaction => {
7006
7188
  typeMapDelete(transaction, this, key);
7007
7189
  });
7008
7190
  } else {
@@ -7020,7 +7202,7 @@ class YMap extends AbstractType {
7020
7202
  */
7021
7203
  set (key, value) {
7022
7204
  if (this.doc !== null) {
7023
- transact(this.doc, transaction => {
7205
+ transact$1(this.doc, transaction => {
7024
7206
  typeMapSet(transaction, this, key, /** @type {any} */ (value));
7025
7207
  });
7026
7208
  } else {
@@ -7054,7 +7236,7 @@ class YMap extends AbstractType {
7054
7236
  */
7055
7237
  clear () {
7056
7238
  if (this.doc !== null) {
7057
- transact(this.doc, transaction => {
7239
+ transact$1(this.doc, transaction => {
7058
7240
  this.forEach(function (_value, key, map) {
7059
7241
  typeMapDelete(transaction, map, key);
7060
7242
  });
@@ -7080,6 +7262,11 @@ class YMap extends AbstractType {
7080
7262
  */
7081
7263
  const readYMap = _decoder => new YMap();
7082
7264
 
7265
+ /**
7266
+ * @module YText
7267
+ */
7268
+
7269
+
7083
7270
  /**
7084
7271
  * @param {any} a
7085
7272
  * @param {any} b
@@ -7164,14 +7351,15 @@ const findNextPosition = (transaction, pos, count) => {
7164
7351
  * @param {Transaction} transaction
7165
7352
  * @param {AbstractType<any>} parent
7166
7353
  * @param {number} index
7354
+ * @param {boolean} useSearchMarker
7167
7355
  * @return {ItemTextListPosition}
7168
7356
  *
7169
7357
  * @private
7170
7358
  * @function
7171
7359
  */
7172
- const findPosition = (transaction, parent, index) => {
7360
+ const findPosition = (transaction, parent, index, useSearchMarker) => {
7173
7361
  const currentAttributes = new Map();
7174
- const marker = findMarker(parent, index);
7362
+ const marker = useSearchMarker ? findMarker(parent, index) : null;
7175
7363
  if (marker) {
7176
7364
  const pos = new ItemTextListPosition(marker.p.left, marker.p, marker.index, currentAttributes);
7177
7365
  return findNextPosition(transaction, pos, index - marker.index)
@@ -7247,7 +7435,7 @@ const minimizeAttributeChanges = (currPos, attributes) => {
7247
7435
  while (true) {
7248
7436
  if (currPos.right === null) {
7249
7437
  break
7250
- } else if (currPos.right.deleted || (currPos.right.content.constructor === ContentFormat && equalAttrs(attributes[(/** @type {ContentFormat} */ (currPos.right.content)).key] || null, /** @type {ContentFormat} */ (currPos.right.content).value))) ; else {
7438
+ } else if (currPos.right.deleted || (currPos.right.content.constructor === ContentFormat && equalAttrs(attributes[(/** @type {ContentFormat} */ (currPos.right.content)).key] ?? null, /** @type {ContentFormat} */ (currPos.right.content).value))) ; else {
7251
7439
  break
7252
7440
  }
7253
7441
  currPos.forward();
@@ -7271,7 +7459,7 @@ const insertAttributes = (transaction, parent, currPos, attributes) => {
7271
7459
  // insert format-start items
7272
7460
  for (const key in attributes) {
7273
7461
  const val = attributes[key];
7274
- const currentVal = currPos.currentAttributes.get(key) || null;
7462
+ const currentVal = currPos.currentAttributes.get(key) ?? null;
7275
7463
  if (!equalAttrs(currentVal, val)) {
7276
7464
  // save negated attribute (set null if currentVal undefined)
7277
7465
  negatedAttributes.set(key, currentVal);
@@ -7433,12 +7621,12 @@ const cleanupFormattingGap = (transaction, start, curr, startAttributes, currAtt
7433
7621
  switch (content.constructor) {
7434
7622
  case ContentFormat: {
7435
7623
  const { key, value } = /** @type {ContentFormat} */ (content);
7436
- const startAttrValue = startAttributes.get(key) || null;
7624
+ const startAttrValue = startAttributes.get(key) ?? null;
7437
7625
  if (endFormats.get(key) !== content || startAttrValue === value) {
7438
7626
  // Either this format is overwritten or it is not necessary because the attribute already existed.
7439
7627
  start.delete(transaction);
7440
7628
  cleanups++;
7441
- if (!reachedCurr && (currAttributes.get(key) || null) === value && startAttrValue !== value) {
7629
+ if (!reachedCurr && (currAttributes.get(key) ?? null) === value && startAttrValue !== value) {
7442
7630
  if (startAttrValue === null) {
7443
7631
  currAttributes.delete(key);
7444
7632
  } else {
@@ -7496,7 +7684,7 @@ const cleanupContextlessFormattingGap = (transaction, item) => {
7496
7684
  */
7497
7685
  const cleanupYTextFormatting = type => {
7498
7686
  let res = 0;
7499
- transact(/** @type {Doc} */ (type.doc), transaction => {
7687
+ transact$1(/** @type {Doc} */ (type.doc), transaction => {
7500
7688
  let start = /** @type {Item} */ (type._start);
7501
7689
  let end = type._start;
7502
7690
  let startAttributes = create$5();
@@ -7521,7 +7709,7 @@ const cleanupYTextFormatting = type => {
7521
7709
  };
7522
7710
 
7523
7711
  /**
7524
- * This will be called by the transction once the event handlers are called to potentially cleanup
7712
+ * This will be called by the transaction once the event handlers are called to potentially cleanup
7525
7713
  * formatting attributes.
7526
7714
  *
7527
7715
  * @param {Transaction} transaction
@@ -7547,7 +7735,7 @@ const cleanupYTextAfterTransaction = transaction => {
7547
7735
  });
7548
7736
  }
7549
7737
  // cleanup in a new transaction
7550
- transact(doc, (t) => {
7738
+ transact$1(doc, (t) => {
7551
7739
  iterateDeletedStructs(transaction, transaction.deleteSet, item => {
7552
7740
  if (item instanceof GC || !(/** @type {YText} */ (item.parent)._hasFormatting) || needFullCleanup.has(/** @type {YText} */ (item.parent))) {
7553
7741
  return
@@ -7611,7 +7799,7 @@ const deleteText = (transaction, currPos, length) => {
7611
7799
 
7612
7800
  /**
7613
7801
  * The Quill Delta format represents changes on a text document with
7614
- * formatting information. For mor information visit {@link https://quilljs.com/docs/delta/|Quill Delta}
7802
+ * formatting information. For more information visit {@link https://quilljs.com/docs/delta/|Quill Delta}
7615
7803
  *
7616
7804
  * @example
7617
7805
  * {
@@ -7702,7 +7890,7 @@ class YTextEvent extends YEvent {
7702
7890
  * @type {Array<{insert?:string|object|AbstractType<any>, delete?:number, retain?:number, attributes?: Object<string,any>}>}
7703
7891
  */
7704
7892
  const delta = [];
7705
- transact(y, transaction => {
7893
+ transact$1(y, transaction => {
7706
7894
  const currentAttributes = new Map(); // saves all current attributes for insert
7707
7895
  const oldAttributes = new Map();
7708
7896
  let item = this.target._start;
@@ -7813,12 +8001,12 @@ class YTextEvent extends YEvent {
7813
8001
  const { key, value } = /** @type {ContentFormat} */ (item.content);
7814
8002
  if (this.adds(item)) {
7815
8003
  if (!this.deletes(item)) {
7816
- const curVal = currentAttributes.get(key) || null;
8004
+ const curVal = currentAttributes.get(key) ?? null;
7817
8005
  if (!equalAttrs(curVal, value)) {
7818
8006
  if (action === 'retain') {
7819
8007
  addOp();
7820
8008
  }
7821
- if (equalAttrs(value, (oldAttributes.get(key) || null))) {
8009
+ if (equalAttrs(value, (oldAttributes.get(key) ?? null))) {
7822
8010
  delete attributes[key];
7823
8011
  } else {
7824
8012
  attributes[key] = value;
@@ -7829,7 +8017,7 @@ class YTextEvent extends YEvent {
7829
8017
  }
7830
8018
  } else if (this.deletes(item)) {
7831
8019
  oldAttributes.set(key, value);
7832
- const curVal = currentAttributes.get(key) || null;
8020
+ const curVal = currentAttributes.get(key) ?? null;
7833
8021
  if (!equalAttrs(curVal, value)) {
7834
8022
  if (action === 'retain') {
7835
8023
  addOp();
@@ -7919,6 +8107,7 @@ class YText extends AbstractType {
7919
8107
  * @type {number}
7920
8108
  */
7921
8109
  get length () {
8110
+ this.doc ?? warnPrematureAccess();
7922
8111
  return this._length
7923
8112
  }
7924
8113
 
@@ -7941,6 +8130,10 @@ class YText extends AbstractType {
7941
8130
  }
7942
8131
 
7943
8132
  /**
8133
+ * Makes a copy of this data type that can be included somewhere else.
8134
+ *
8135
+ * Note that the content is only readable _after_ it has been included somewhere in the Ydoc.
8136
+ *
7944
8137
  * @return {YText}
7945
8138
  */
7946
8139
  clone () {
@@ -7971,6 +8164,7 @@ class YText extends AbstractType {
7971
8164
  * @public
7972
8165
  */
7973
8166
  toString () {
8167
+ this.doc ?? warnPrematureAccess();
7974
8168
  let str = '';
7975
8169
  /**
7976
8170
  * @type {Item|null}
@@ -7998,7 +8192,7 @@ class YText extends AbstractType {
7998
8192
  /**
7999
8193
  * Apply a {@link Delta} on this shared YText type.
8000
8194
  *
8001
- * @param {any} delta The changes to apply on this element.
8195
+ * @param {Array<any>} delta The changes to apply on this element.
8002
8196
  * @param {object} opts
8003
8197
  * @param {boolean} [opts.sanitize] Sanitize input delta. Removes ending newlines if set to true.
8004
8198
  *
@@ -8007,7 +8201,7 @@ class YText extends AbstractType {
8007
8201
  */
8008
8202
  applyDelta (delta, { sanitize = true } = {}) {
8009
8203
  if (this.doc !== null) {
8010
- transact(this.doc, transaction => {
8204
+ transact$1(this.doc, transaction => {
8011
8205
  const currPos = new ItemTextListPosition(null, this._start, 0, new Map());
8012
8206
  for (let i = 0; i < delta.length; i++) {
8013
8207
  const op = delta[i];
@@ -8044,6 +8238,7 @@ class YText extends AbstractType {
8044
8238
  * @public
8045
8239
  */
8046
8240
  toDelta (snapshot, prevSnapshot, computeYChange) {
8241
+ this.doc ?? warnPrematureAccess();
8047
8242
  /**
8048
8243
  * @type{Array<any>}
8049
8244
  */
@@ -8132,7 +8327,7 @@ class YText extends AbstractType {
8132
8327
  if (snapshot || prevSnapshot) {
8133
8328
  // snapshots are merged again after the transaction, so we need to keep the
8134
8329
  // transaction alive until we are done
8135
- transact(doc, transaction => {
8330
+ transact$1(doc, transaction => {
8136
8331
  if (snapshot) {
8137
8332
  splitSnapshotAffectedStructs(transaction, snapshot);
8138
8333
  }
@@ -8163,8 +8358,8 @@ class YText extends AbstractType {
8163
8358
  }
8164
8359
  const y = this.doc;
8165
8360
  if (y !== null) {
8166
- transact(y, transaction => {
8167
- const pos = findPosition(transaction, this, index);
8361
+ transact$1(y, transaction => {
8362
+ const pos = findPosition(transaction, this, index, !attributes);
8168
8363
  if (!attributes) {
8169
8364
  attributes = {};
8170
8365
  // @ts-ignore
@@ -8182,20 +8377,20 @@ class YText extends AbstractType {
8182
8377
  *
8183
8378
  * @param {number} index The index to insert the embed at.
8184
8379
  * @param {Object | AbstractType<any>} embed The Object that represents the embed.
8185
- * @param {TextAttributes} attributes Attribute information to apply on the
8380
+ * @param {TextAttributes} [attributes] Attribute information to apply on the
8186
8381
  * embed
8187
8382
  *
8188
8383
  * @public
8189
8384
  */
8190
- insertEmbed (index, embed, attributes = {}) {
8385
+ insertEmbed (index, embed, attributes) {
8191
8386
  const y = this.doc;
8192
8387
  if (y !== null) {
8193
- transact(y, transaction => {
8194
- const pos = findPosition(transaction, this, index);
8195
- insertText(transaction, this, pos, embed, attributes);
8388
+ transact$1(y, transaction => {
8389
+ const pos = findPosition(transaction, this, index, !attributes);
8390
+ insertText(transaction, this, pos, embed, attributes || {});
8196
8391
  });
8197
8392
  } else {
8198
- /** @type {Array<function>} */ (this._pending).push(() => this.insertEmbed(index, embed, attributes));
8393
+ /** @type {Array<function>} */ (this._pending).push(() => this.insertEmbed(index, embed, attributes || {}));
8199
8394
  }
8200
8395
  }
8201
8396
 
@@ -8213,8 +8408,8 @@ class YText extends AbstractType {
8213
8408
  }
8214
8409
  const y = this.doc;
8215
8410
  if (y !== null) {
8216
- transact(y, transaction => {
8217
- deleteText(transaction, findPosition(transaction, this, index), length);
8411
+ transact$1(y, transaction => {
8412
+ deleteText(transaction, findPosition(transaction, this, index, true), length);
8218
8413
  });
8219
8414
  } else {
8220
8415
  /** @type {Array<function>} */ (this._pending).push(() => this.delete(index, length));
@@ -8237,8 +8432,8 @@ class YText extends AbstractType {
8237
8432
  }
8238
8433
  const y = this.doc;
8239
8434
  if (y !== null) {
8240
- transact(y, transaction => {
8241
- const pos = findPosition(transaction, this, index);
8435
+ transact$1(y, transaction => {
8436
+ const pos = findPosition(transaction, this, index, false);
8242
8437
  if (pos.right === null) {
8243
8438
  return
8244
8439
  }
@@ -8260,7 +8455,7 @@ class YText extends AbstractType {
8260
8455
  */
8261
8456
  removeAttribute (attributeName) {
8262
8457
  if (this.doc !== null) {
8263
- transact(this.doc, transaction => {
8458
+ transact$1(this.doc, transaction => {
8264
8459
  typeMapDelete(transaction, this, attributeName);
8265
8460
  });
8266
8461
  } else {
@@ -8280,7 +8475,7 @@ class YText extends AbstractType {
8280
8475
  */
8281
8476
  setAttribute (attributeName, attributeValue) {
8282
8477
  if (this.doc !== null) {
8283
- transact(this.doc, transaction => {
8478
+ transact$1(this.doc, transaction => {
8284
8479
  typeMapSet(transaction, this, attributeName, attributeValue);
8285
8480
  });
8286
8481
  } else {
@@ -8337,6 +8532,7 @@ const readYText = _decoder => new YText();
8337
8532
  * @module YXml
8338
8533
  */
8339
8534
 
8535
+
8340
8536
  /**
8341
8537
  * Define the elements to which a set of CSS queries apply.
8342
8538
  * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors|CSS_Selectors}
@@ -8380,6 +8576,7 @@ class YXmlTreeWalker {
8380
8576
  */
8381
8577
  this._currentNode = /** @type {Item} */ (root._start);
8382
8578
  this._firstCall = true;
8579
+ root.doc ?? warnPrematureAccess();
8383
8580
  }
8384
8581
 
8385
8582
  [Symbol.iterator] () {
@@ -8408,8 +8605,12 @@ class YXmlTreeWalker {
8408
8605
  } else {
8409
8606
  // walk right or up in the tree
8410
8607
  while (n !== null) {
8411
- if (n.right !== null) {
8412
- n = n.right;
8608
+ /**
8609
+ * @type {Item | null}
8610
+ */
8611
+ const nxt = n.next;
8612
+ if (nxt !== null) {
8613
+ n = nxt;
8413
8614
  break
8414
8615
  } else if (n.parent === this._root) {
8415
8616
  n = null;
@@ -8477,6 +8678,10 @@ class YXmlFragment extends AbstractType {
8477
8678
  }
8478
8679
 
8479
8680
  /**
8681
+ * Makes a copy of this data type that can be included somewhere else.
8682
+ *
8683
+ * Note that the content is only readable _after_ it has been included somewhere in the Ydoc.
8684
+ *
8480
8685
  * @return {YXmlFragment}
8481
8686
  */
8482
8687
  clone () {
@@ -8487,6 +8692,7 @@ class YXmlFragment extends AbstractType {
8487
8692
  }
8488
8693
 
8489
8694
  get length () {
8695
+ this.doc ?? warnPrematureAccess();
8490
8696
  return this._prelimContent === null ? this._length : this._prelimContent.length
8491
8697
  }
8492
8698
 
@@ -8619,7 +8825,7 @@ class YXmlFragment extends AbstractType {
8619
8825
  */
8620
8826
  insert (index, content) {
8621
8827
  if (this.doc !== null) {
8622
- transact(this.doc, transaction => {
8828
+ transact$1(this.doc, transaction => {
8623
8829
  typeListInsertGenerics(transaction, this, index, content);
8624
8830
  });
8625
8831
  } else {
@@ -8640,7 +8846,7 @@ class YXmlFragment extends AbstractType {
8640
8846
  */
8641
8847
  insertAfter (ref, content) {
8642
8848
  if (this.doc !== null) {
8643
- transact(this.doc, transaction => {
8849
+ transact$1(this.doc, transaction => {
8644
8850
  const refItem = (ref && ref instanceof AbstractType) ? ref._item : ref;
8645
8851
  typeListInsertGenericsAfter(transaction, this, refItem, content);
8646
8852
  });
@@ -8662,7 +8868,7 @@ class YXmlFragment extends AbstractType {
8662
8868
  */
8663
8869
  delete (index, length = 1) {
8664
8870
  if (this.doc !== null) {
8665
- transact(this.doc, transaction => {
8871
+ transact$1(this.doc, transaction => {
8666
8872
  typeListDelete(transaction, this, index, length);
8667
8873
  });
8668
8874
  } else {
@@ -8690,9 +8896,9 @@ class YXmlFragment extends AbstractType {
8690
8896
  }
8691
8897
 
8692
8898
  /**
8693
- * Preppends content to this YArray.
8899
+ * Prepends content to this YArray.
8694
8900
  *
8695
- * @param {Array<YXmlElement|YXmlText>} content Array of content to preppend.
8901
+ * @param {Array<YXmlElement|YXmlText>} content Array of content to prepend.
8696
8902
  */
8697
8903
  unshift (content) {
8698
8904
  this.insert(0, content);
@@ -8709,7 +8915,8 @@ class YXmlFragment extends AbstractType {
8709
8915
  }
8710
8916
 
8711
8917
  /**
8712
- * Transforms this YArray to a JavaScript Array.
8918
+ * Returns a portion of this YXmlFragment into a JavaScript Array selected
8919
+ * from start to end (end not included).
8713
8920
  *
8714
8921
  * @param {number} [start]
8715
8922
  * @param {number} [end]
@@ -8720,7 +8927,7 @@ class YXmlFragment extends AbstractType {
8720
8927
  }
8721
8928
 
8722
8929
  /**
8723
- * Executes a provided function on once on overy child element.
8930
+ * Executes a provided function on once on every child element.
8724
8931
  *
8725
8932
  * @param {function(YXmlElement|YXmlText,number, typeof self):void} f A function to execute on every element of this YArray.
8726
8933
  */
@@ -8756,7 +8963,7 @@ const readYXmlFragment = _decoder => new YXmlFragment();
8756
8963
 
8757
8964
  /**
8758
8965
  * An YXmlElement imitates the behavior of a
8759
- * {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element}.
8966
+ * https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element
8760
8967
  *
8761
8968
  * * An YXmlElement has attributes (key value pairs)
8762
8969
  * * An YXmlElement has childElements that must inherit from YXmlElement
@@ -8817,6 +9024,10 @@ class YXmlElement extends YXmlFragment {
8817
9024
  }
8818
9025
 
8819
9026
  /**
9027
+ * Makes a copy of this data type that can be included somewhere else.
9028
+ *
9029
+ * Note that the content is only readable _after_ it has been included somewhere in the Ydoc.
9030
+ *
8820
9031
  * @return {YXmlElement<KV>}
8821
9032
  */
8822
9033
  clone () {
@@ -8871,7 +9082,7 @@ class YXmlElement extends YXmlFragment {
8871
9082
  */
8872
9083
  removeAttribute (attributeName) {
8873
9084
  if (this.doc !== null) {
8874
- transact(this.doc, transaction => {
9085
+ transact$1(this.doc, transaction => {
8875
9086
  typeMapDelete(transaction, this, attributeName);
8876
9087
  });
8877
9088
  } else {
@@ -8891,7 +9102,7 @@ class YXmlElement extends YXmlFragment {
8891
9102
  */
8892
9103
  setAttribute (attributeName, attributeValue) {
8893
9104
  if (this.doc !== null) {
8894
- transact(this.doc, transaction => {
9105
+ transact$1(this.doc, transaction => {
8895
9106
  typeMapSet(transaction, this, attributeName, attributeValue);
8896
9107
  });
8897
9108
  } else {
@@ -8929,12 +9140,13 @@ class YXmlElement extends YXmlFragment {
8929
9140
  /**
8930
9141
  * Returns all attribute name/value pairs in a JSON Object.
8931
9142
  *
9143
+ * @param {Snapshot} [snapshot]
8932
9144
  * @return {{ [Key in Extract<keyof KV,string>]?: KV[Key]}} A JSON Object that describes the attributes.
8933
9145
  *
8934
9146
  * @public
8935
9147
  */
8936
- getAttributes () {
8937
- return /** @type {any} */ (typeMapGetAll(this))
9148
+ getAttributes (snapshot) {
9149
+ return /** @type {any} */ (snapshot ? typeMapGetAllSnapshot(this, snapshot) : typeMapGetAll(this))
8938
9150
  }
8939
9151
 
8940
9152
  /**
@@ -9001,7 +9213,7 @@ class YXmlEvent extends YEvent {
9001
9213
  * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created.
9002
9214
  * @param {Set<string|null>} subs The set of changed attributes. `null` is included if the
9003
9215
  * child list changed.
9004
- * @param {Transaction} transaction The transaction instance with wich the
9216
+ * @param {Transaction} transaction The transaction instance with which the
9005
9217
  * change was created.
9006
9218
  */
9007
9219
  constructor (target, subs, transaction) {
@@ -9052,6 +9264,10 @@ class YXmlHook extends YMap {
9052
9264
  }
9053
9265
 
9054
9266
  /**
9267
+ * Makes a copy of this data type that can be included somewhere else.
9268
+ *
9269
+ * Note that the content is only readable _after_ it has been included somewhere in the Ydoc.
9270
+ *
9055
9271
  * @return {YXmlHook}
9056
9272
  */
9057
9273
  clone () {
@@ -9142,6 +9358,10 @@ class YXmlText extends YText {
9142
9358
  }
9143
9359
 
9144
9360
  /**
9361
+ * Makes a copy of this data type that can be included somewhere else.
9362
+ *
9363
+ * Note that the content is only readable _after_ it has been included somewhere in the Ydoc.
9364
+ *
9145
9365
  * @return {YXmlText}
9146
9366
  */
9147
9367
  clone () {
@@ -9253,7 +9473,7 @@ class AbstractStruct {
9253
9473
  * This method is already assuming that `this.id.clock + this.length === this.id.clock`.
9254
9474
  * Also this method does *not* remove right from StructStore!
9255
9475
  * @param {AbstractStruct} right
9256
- * @return {boolean} wether this merged with right
9476
+ * @return {boolean} whether this merged with right
9257
9477
  */
9258
9478
  mergeWith (right) {
9259
9479
  return false
@@ -9956,6 +10176,8 @@ const readContentJSON = decoder => {
9956
10176
  return new ContentJSON(cs)
9957
10177
  };
9958
10178
 
10179
+ const isDevMode = getVariable('node_env') === 'development';
10180
+
9959
10181
  class ContentAny {
9960
10182
  /**
9961
10183
  * @param {Array<any>} arr
@@ -9965,6 +10187,7 @@ class ContentAny {
9965
10187
  * @type {Array<any>}
9966
10188
  */
9967
10189
  this.arr = arr;
10190
+ isDevMode && deepFreeze(arr);
9968
10191
  }
9969
10192
 
9970
10193
  /**
@@ -10525,14 +10748,12 @@ class Item extends AbstractStruct {
10525
10748
  }
10526
10749
  if ((this.left && this.left.constructor === GC) || (this.right && this.right.constructor === GC)) {
10527
10750
  this.parent = null;
10528
- }
10529
- // only set parent if this shouldn't be garbage collected
10530
- if (!this.parent) {
10751
+ } else if (!this.parent) {
10752
+ // only set parent if this shouldn't be garbage collected
10531
10753
  if (this.left && this.left.constructor === Item) {
10532
10754
  this.parent = this.left.parent;
10533
10755
  this.parentSub = this.left.parentSub;
10534
- }
10535
- if (this.right && this.right.constructor === Item) {
10756
+ } else if (this.right && this.right.constructor === Item) {
10536
10757
  this.parent = this.right.parent;
10537
10758
  this.parentSub = this.right.parentSub;
10538
10759
  }
@@ -10913,6 +11134,7 @@ class Skip extends AbstractStruct {
10913
11134
 
10914
11135
  /** eslint-env browser */
10915
11136
 
11137
+
10916
11138
  const glo = /** @type {any} */ (typeof globalThis !== 'undefined'
10917
11139
  ? globalThis
10918
11140
  : typeof window !== 'undefined'
@@ -10941,67 +11163,86 @@ if (glo[importIdentifier] === true) {
10941
11163
  }
10942
11164
  glo[importIdentifier] = true;
10943
11165
 
10944
- const t=Symbol();const s$1=Object.getPrototypeOf,c$1=new WeakMap,l$1=e=>e&&(c$1.has(e)?c$1.get(e):s$1(e)===Object.prototype||s$1(e)===Array.prototype),y=e=>l$1(e)&&e[t]||null,h=(e,t=!0)=>{c$1.set(e,t);};
11166
+ /* eslint @typescript-eslint/no-explicit-any: off */
11167
+ // symbols
11168
+ const GET_ORIGINAL_SYMBOL = Symbol();
11169
+ // get object prototype
11170
+ const getProto$2 = Object.getPrototypeOf;
11171
+ const objectsToTrack = new WeakMap();
11172
+ // check if obj is a plain object or an array
11173
+ const isObjectToTrack = (obj) => obj &&
11174
+ (objectsToTrack.has(obj)
11175
+ ? objectsToTrack.get(obj)
11176
+ : getProto$2(obj) === Object.prototype || getProto$2(obj) === Array.prototype);
11177
+ /**
11178
+ * Unwrap proxy to get the original object.
11179
+ *
11180
+ * Used to retrieve the original object used to create the proxy instance with `createProxy`.
11181
+ *
11182
+ * @param {Proxy<object>} obj - The proxy wrapper of the originial object.
11183
+ * @returns {object | null} - Return either the unwrapped object if exists.
11184
+ *
11185
+ * @example
11186
+ * import { createProxy, getUntracked } from 'proxy-compare';
11187
+ *
11188
+ * const original = { a: "1", c: "2", d: { e: "3" } };
11189
+ * const affected = new WeakMap();
11190
+ *
11191
+ * const proxy = createProxy(original, affected);
11192
+ * const originalFromProxy = getUntracked(proxy)
11193
+ *
11194
+ * Object.is(original, originalFromProxy) // true
11195
+ * isChanged(original, originalFromProxy, affected) // false
11196
+ */
11197
+ const getUntracked = (obj) => {
11198
+ if (isObjectToTrack(obj)) {
11199
+ return obj[GET_ORIGINAL_SYMBOL] || null;
11200
+ }
11201
+ return null;
11202
+ };
10945
11203
 
10946
11204
  const isObject = (x) => typeof x === "object" && x !== null;
10947
- const proxyStateMap = /* @__PURE__ */ new WeakMap();
10948
- const refSet = /* @__PURE__ */ new WeakSet();
10949
- const buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) => new Proxy(target, handler), canProxy = (x) => isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer), defaultHandlePromise = (promise) => {
10950
- switch (promise.status) {
10951
- case "fulfilled":
10952
- return promise.value;
10953
- case "rejected":
10954
- throw promise.reason;
10955
- default:
10956
- throw promise;
10957
- }
10958
- }, snapCache = /* @__PURE__ */ new WeakMap(), createSnapshot = (target, version, handlePromise = defaultHandlePromise) => {
10959
- const cache = snapCache.get(target);
10960
- if ((cache == null ? void 0 : cache[0]) === version) {
10961
- return cache[1];
10962
- }
10963
- const snap = Array.isArray(target) ? [] : Object.create(Object.getPrototypeOf(target));
10964
- h(snap, true);
10965
- snapCache.set(target, [version, snap]);
10966
- Reflect.ownKeys(target).forEach((key) => {
10967
- if (Object.getOwnPropertyDescriptor(snap, key)) {
10968
- return;
11205
+ const canProxyDefault = (x) => isObject(x) && !refSet.has(x) && (Array.isArray(x) || !(Symbol.iterator in x)) && !(x instanceof WeakMap) && !(x instanceof WeakSet) && !(x instanceof Error) && !(x instanceof Number) && !(x instanceof Date) && !(x instanceof String) && !(x instanceof RegExp) && !(x instanceof ArrayBuffer) && !(x instanceof Promise);
11206
+ const createHandlerDefault = (isInitializing, addPropListener, removePropListener, notifyUpdate) => ({
11207
+ deleteProperty(target, prop) {
11208
+ const prevValue = Reflect.get(target, prop);
11209
+ removePropListener(prop);
11210
+ const deleted = Reflect.deleteProperty(target, prop);
11211
+ if (deleted) {
11212
+ notifyUpdate(["delete", [prop], prevValue]);
11213
+ }
11214
+ return deleted;
11215
+ },
11216
+ set(target, prop, value, receiver) {
11217
+ const hasPrevValue = !isInitializing() && Reflect.has(target, prop);
11218
+ const prevValue = Reflect.get(target, prop, receiver);
11219
+ if (hasPrevValue && (objectIs(prevValue, value) || proxyCache.has(value) && objectIs(prevValue, proxyCache.get(value)))) {
11220
+ return true;
10969
11221
  }
10970
- const value = Reflect.get(target, key);
10971
- const { enumerable } = Reflect.getOwnPropertyDescriptor(
10972
- target,
10973
- key
10974
- );
10975
- const desc = {
10976
- value,
10977
- enumerable,
10978
- // This is intentional to avoid copying with proxy-compare.
10979
- // It's still non-writable, so it avoids assigning a value.
10980
- configurable: true
10981
- };
10982
- if (refSet.has(value)) {
10983
- h(value, false);
10984
- } else if (value instanceof Promise) {
10985
- delete desc.value;
10986
- desc.get = () => handlePromise(value);
10987
- } else if (proxyStateMap.has(value)) {
10988
- const [target2, ensureVersion] = proxyStateMap.get(
10989
- value
10990
- );
10991
- desc.value = createSnapshot(
10992
- target2,
10993
- ensureVersion(),
10994
- handlePromise
10995
- );
11222
+ removePropListener(prop);
11223
+ if (isObject(value)) {
11224
+ value = getUntracked(value) || value;
10996
11225
  }
10997
- Object.defineProperty(snap, key, desc);
10998
- });
10999
- return Object.preventExtensions(snap);
11000
- }, proxyCache = /* @__PURE__ */ new WeakMap(), versionHolder = [1, 1], proxyFunction = (initialObject) => {
11001
- if (!isObject(initialObject)) {
11226
+ const nextValue = !proxyStateMap.has(value) && canProxy(value) ? proxy(value) : value;
11227
+ addPropListener(prop, nextValue);
11228
+ Reflect.set(target, prop, nextValue, receiver);
11229
+ notifyUpdate(["set", [prop], value, prevValue]);
11230
+ return true;
11231
+ }
11232
+ });
11233
+ const proxyStateMap = /* @__PURE__ */ new WeakMap();
11234
+ const refSet = /* @__PURE__ */ new WeakSet();
11235
+ const versionHolder = [1, 1];
11236
+ const proxyCache = /* @__PURE__ */ new WeakMap();
11237
+ let objectIs = Object.is;
11238
+ let newProxy = (target, handler) => new Proxy(target, handler);
11239
+ let canProxy = canProxyDefault;
11240
+ let createHandler = createHandlerDefault;
11241
+ function proxy(baseObject = {}) {
11242
+ if (!isObject(baseObject)) {
11002
11243
  throw new Error("object required");
11003
11244
  }
11004
- const found = proxyCache.get(initialObject);
11245
+ const found = proxyCache.get(baseObject);
11005
11246
  if (found) {
11006
11247
  return found;
11007
11248
  }
@@ -11032,15 +11273,18 @@ const buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) =
11032
11273
  notifyUpdate(newOp, nextVersion);
11033
11274
  };
11034
11275
  const propProxyStates = /* @__PURE__ */ new Map();
11035
- const addPropListener = (prop, propProxyState) => {
11036
- if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && propProxyStates.has(prop)) {
11037
- throw new Error("prop listener already exists");
11038
- }
11039
- if (listeners.size) {
11040
- const remove = propProxyState[3](createPropListener(prop));
11041
- propProxyStates.set(prop, [propProxyState, remove]);
11042
- } else {
11043
- propProxyStates.set(prop, [propProxyState]);
11276
+ const addPropListener = (prop, propValue) => {
11277
+ const propProxyState = !refSet.has(propValue) && proxyStateMap.get(propValue);
11278
+ if (propProxyState) {
11279
+ if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && propProxyStates.has(prop)) {
11280
+ throw new Error("prop listener already exists");
11281
+ }
11282
+ if (listeners.size) {
11283
+ const remove = propProxyState[2](createPropListener(prop));
11284
+ propProxyStates.set(prop, [propProxyState, remove]);
11285
+ } else {
11286
+ propProxyStates.set(prop, [propProxyState]);
11287
+ }
11044
11288
  }
11045
11289
  };
11046
11290
  const removePropListener = (prop) => {
@@ -11058,7 +11302,7 @@ const buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) =
11058
11302
  if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && prevRemove) {
11059
11303
  throw new Error("remove already exists");
11060
11304
  }
11061
- const remove = propProxyState[3](createPropListener(prop));
11305
+ const remove = propProxyState[2](createPropListener(prop));
11062
11306
  propProxyStates.set(prop, [propProxyState, remove]);
11063
11307
  });
11064
11308
  }
@@ -11075,93 +11319,28 @@ const buildProxyFunction = (objectIs = Object.is, newProxy = (target, handler) =
11075
11319
  };
11076
11320
  return removeListener;
11077
11321
  };
11078
- const baseObject = Array.isArray(initialObject) ? [] : Object.create(Object.getPrototypeOf(initialObject));
11079
- const handler = {
11080
- deleteProperty(target, prop) {
11081
- const prevValue = Reflect.get(target, prop);
11082
- removePropListener(prop);
11083
- const deleted = Reflect.deleteProperty(target, prop);
11084
- if (deleted) {
11085
- notifyUpdate(["delete", [prop], prevValue]);
11086
- }
11087
- return deleted;
11088
- },
11089
- set(target, prop, value, receiver) {
11090
- const hasPrevValue = Reflect.has(target, prop);
11091
- const prevValue = Reflect.get(target, prop, receiver);
11092
- if (hasPrevValue && (objectIs(prevValue, value) || proxyCache.has(value) && objectIs(prevValue, proxyCache.get(value)))) {
11093
- return true;
11094
- }
11095
- removePropListener(prop);
11096
- if (isObject(value)) {
11097
- value = y(value) || value;
11098
- }
11099
- let nextValue = value;
11100
- if (value instanceof Promise) {
11101
- value.then((v) => {
11102
- value.status = "fulfilled";
11103
- value.value = v;
11104
- notifyUpdate(["resolve", [prop], v]);
11105
- }).catch((e) => {
11106
- value.status = "rejected";
11107
- value.reason = e;
11108
- notifyUpdate(["reject", [prop], e]);
11109
- });
11110
- } else {
11111
- if (!proxyStateMap.has(value) && canProxy(value)) {
11112
- nextValue = proxyFunction(value);
11113
- }
11114
- const childProxyState = !refSet.has(nextValue) && proxyStateMap.get(nextValue);
11115
- if (childProxyState) {
11116
- addPropListener(prop, childProxyState);
11117
- }
11118
- }
11119
- Reflect.set(target, prop, nextValue, receiver);
11120
- notifyUpdate(["set", [prop], value, prevValue]);
11121
- return true;
11122
- }
11123
- };
11322
+ let initializing = true;
11323
+ const handler = createHandler(
11324
+ () => initializing,
11325
+ addPropListener,
11326
+ removePropListener,
11327
+ notifyUpdate
11328
+ );
11124
11329
  const proxyObject = newProxy(baseObject, handler);
11125
- proxyCache.set(initialObject, proxyObject);
11126
- const proxyState = [
11127
- baseObject,
11128
- ensureVersion,
11129
- createSnapshot,
11130
- addListener
11131
- ];
11330
+ proxyCache.set(baseObject, proxyObject);
11331
+ const proxyState = [baseObject, ensureVersion, addListener];
11132
11332
  proxyStateMap.set(proxyObject, proxyState);
11133
- Reflect.ownKeys(initialObject).forEach((key) => {
11333
+ Reflect.ownKeys(baseObject).forEach((key) => {
11134
11334
  const desc = Object.getOwnPropertyDescriptor(
11135
- initialObject,
11335
+ baseObject,
11136
11336
  key
11137
11337
  );
11138
- if ("value" in desc) {
11139
- proxyObject[key] = initialObject[key];
11140
- delete desc.value;
11141
- delete desc.writable;
11338
+ if ("value" in desc && desc.writable) {
11339
+ proxyObject[key] = baseObject[key];
11142
11340
  }
11143
- Object.defineProperty(baseObject, key, desc);
11144
11341
  });
11342
+ initializing = false;
11145
11343
  return proxyObject;
11146
- }) => [
11147
- // public functions
11148
- proxyFunction,
11149
- // shared state
11150
- proxyStateMap,
11151
- refSet,
11152
- // internal things
11153
- objectIs,
11154
- newProxy,
11155
- canProxy,
11156
- defaultHandlePromise,
11157
- snapCache,
11158
- createSnapshot,
11159
- proxyCache,
11160
- versionHolder
11161
- ];
11162
- const [defaultProxyFunction] = buildProxyFunction();
11163
- function proxy(initialObject = {}) {
11164
- return defaultProxyFunction(initialObject);
11165
11344
  }
11166
11345
  function getVersion(proxyObject) {
11167
11346
  const proxyState = proxyStateMap.get(proxyObject);
@@ -11174,7 +11353,7 @@ function subscribe(proxyObject, callback, notifyInSync) {
11174
11353
  }
11175
11354
  let promise;
11176
11355
  const ops = [];
11177
- const addListener = proxyState[3];
11356
+ const addListener = proxyState[2];
11178
11357
  let isListenerActive = false;
11179
11358
  const listener = (op) => {
11180
11359
  ops.push(op);
@@ -11244,9 +11423,354 @@ var fastDeepEqual = function equal(a, b) {
11244
11423
  return a!==a && b!==b;
11245
11424
  };
11246
11425
 
11247
- var r = /*@__PURE__*/getDefaultExportFromCjs(fastDeepEqual);
11426
+ var deepEqual = /*@__PURE__*/getDefaultExportFromCjs(fastDeepEqual);
11427
+
11428
+ const parseProxyOps = (ops) => {
11429
+ const arrayOps = ops.flatMap((op) => {
11430
+ if (op[0] === 'resolve' || op[0] === 'reject')
11431
+ return [];
11432
+ const index = Number(op[1][op[1].length - 1]);
11433
+ if (!Number.isFinite(index))
11434
+ return [];
11435
+ return [[op[0], index, op[2], op[3]]];
11436
+ });
11437
+ const findCorrespondingInsert = (startOpIndex, startArrayIndex) => {
11438
+ let s = 0;
11439
+ let noInsert = null;
11440
+ while (startOpIndex + s + 1 < arrayOps.length) {
11441
+ if ((arrayOps[startOpIndex + s + 1][0] === 'set' ||
11442
+ arrayOps[startOpIndex + s + 1][0] === 'insert') &&
11443
+ arrayOps[startOpIndex + s + 1][1] < startArrayIndex &&
11444
+ arrayOps[startOpIndex + s + 1][3] === arrayOps[startOpIndex][2]) {
11445
+ return s + 1;
11446
+ }
11447
+ if (noInsert === null &&
11448
+ (arrayOps[startOpIndex + s + 1][0] === 'set' ||
11449
+ arrayOps[startOpIndex + s + 1][0] === 'insert') &&
11450
+ arrayOps[startOpIndex + s + 1][1] === startArrayIndex - (s + 1) &&
11451
+ arrayOps[startOpIndex + s + 1][3] === undefined) {
11452
+ s += 1;
11453
+ }
11454
+ else if (noInsert === null &&
11455
+ startOpIndex + s + 1 < arrayOps.length &&
11456
+ arrayOps[startOpIndex + s + 1][0] === 'set' &&
11457
+ arrayOps[startOpIndex + s + 1][3] !== undefined) {
11458
+ noInsert = [startOpIndex + s + 1, arrayOps[startOpIndex + s + 1][1]];
11459
+ s += 1;
11460
+ }
11461
+ else if (noInsert !== null &&
11462
+ arrayOps[startOpIndex + s + 1][0] === 'set' &&
11463
+ arrayOps[startOpIndex + s + 1][1] ===
11464
+ noInsert[1] + (s + 1 - noInsert[0]) &&
11465
+ arrayOps[startOpIndex + s + 1][3] !== undefined) {
11466
+ s += 1;
11467
+ }
11468
+ else {
11469
+ return null;
11470
+ }
11471
+ }
11472
+ return null;
11473
+ };
11474
+ const findContinuousDelete = (startOpIndex, startArrayIndex) => {
11475
+ let d = 0;
11476
+ while (startOpIndex + d + 1 < arrayOps.length &&
11477
+ arrayOps[startOpIndex + d + 1][0] === 'delete' &&
11478
+ arrayOps[startOpIndex + d + 1][1] === startArrayIndex - (d + 1)) {
11479
+ d += 1;
11480
+ }
11481
+ return d;
11482
+ };
11483
+ let i = 0;
11484
+ while (i < arrayOps.length) {
11485
+ if ((arrayOps[i][0] === 'set' || arrayOps[i][0] === 'insert') &&
11486
+ arrayOps[i][3] === undefined) {
11487
+ const startArrayIndex = arrayOps[i][1];
11488
+ const s = findCorrespondingInsert(i, startArrayIndex);
11489
+ if (s !== null) {
11490
+ const newArrayOp = [
11491
+ 'insert',
11492
+ arrayOps[i + s][1],
11493
+ arrayOps[i + s][2],
11494
+ undefined,
11495
+ ];
11496
+ arrayOps.splice(i + s, 1, newArrayOp);
11497
+ arrayOps.splice(i, 1);
11498
+ }
11499
+ else {
11500
+ i += 1;
11501
+ }
11502
+ }
11503
+ else if (i > 0 && arrayOps[i][0] === 'delete') {
11504
+ const startArrayIndex = arrayOps[i][1];
11505
+ const d = findContinuousDelete(i, startArrayIndex);
11506
+ if (arrayOps[i - 1][0] === 'set' &&
11507
+ arrayOps[i - 1][1] === startArrayIndex - (d + 1) &&
11508
+ arrayOps[i - 1][2] === arrayOps[i][2]) {
11509
+ const newArrayOp = [
11510
+ 'delete',
11511
+ startArrayIndex - (d + 1),
11512
+ arrayOps[i - 1][3],
11513
+ undefined,
11514
+ ];
11515
+ arrayOps.splice(i - 1, 2);
11516
+ arrayOps.splice(i - 1 + d, 0, newArrayOp);
11517
+ i -= 1;
11518
+ }
11519
+ else {
11520
+ i += 1;
11521
+ }
11522
+ }
11523
+ else {
11524
+ i += 1;
11525
+ }
11526
+ }
11527
+ return arrayOps;
11528
+ };
11248
11529
 
11249
- const o=e=>"object"==typeof e&&null!==e&&void 0!==getVersion(e),s=e=>Array.isArray(e)&&void 0!==getVersion(e),i=(e,t,n)=>{e?e.transact(n,t.transactionOrigin):n();},c=e=>{if(s(e)){const t=new YArray;return t.insert(0,e.map(c).filter(e=>null!=e)),t}if(o(e)){const t=new YMap;return Object.entries(e).forEach(([e,n])=>{const r=c(n);void 0!==r&&t.set(e,r);}),t}if(null===(t=e)||"string"==typeof t||"number"==typeof t||"boolean"==typeof t)return e;var t;},l=e=>e instanceof AbstractType?e.toJSON():e,a=(e,t,r)=>{let o=e,s=t;for(let e=0;e<r.length;e+=1){const t=r[e];if(s instanceof YMap){if(!o)break;o=o[t],s=s.get(t);}else if(s instanceof YArray){if(!o)break;const e=Number(t);o=o[t],s=s.get(e);}else o=null,s=null;}return {p:o,y:s}};function f(t,c,f={}){!s(t)||c instanceof YArray||"production"!=="production",!o(t)||s(t)||c instanceof YMap||"production"!=="production",function(e,t){o(e)&&t instanceof YMap&&t.forEach((t,n)=>{r(e[n],l(t))||(e[n]=l(t));}),s(e)&&t instanceof YArray&&t.forEach((t,n)=>{r(e[n],l(t))||u(t,e,n);});}(t,c),function(e,t,c){i(t.doc,c,()=>{o(e)&&t instanceof YMap&&Object.entries(e).forEach(([e,n])=>{const o=t.get(e);r(n,l(o))||p(n,t,e);}),s(e)&&t instanceof YArray&&e.forEach((e,n)=>{const o=t.get(n);r(e,l(o))||p(e,t,n);});});}(t,c,f),s(t)&&c instanceof YArray&&t.splice(c.length);const y=function(t,o,s){return subscribe(t,e=>{i(o.doc,s,()=>{e.forEach(s=>{const i=s[1].slice(0,-1),c=s[1][s[1].length-1],f=a(t,o,i);if(f.y instanceof YMap){if("delete"===s[0])f.y.delete(c);else if("set"===s[0]){const e=f.p[c],t=f.y.get(c);r(l(t),e)||p(e,f.y,c);}}else if(f.y instanceof YArray){if(r(l(f.y),f.p))return;(e=>{const t=e.flatMap(e=>{if("resolve"===e[0]||"reject"===e[0])return [];const t=Number(e[1][e[1].length-1]);return Number.isFinite(t)?[[e[0],t,e[2],e[3]]]:[]}),n=(e,n)=>{let r=0,o=null;for(;e+r+1<t.length;){if(("set"===t[e+r+1][0]||"insert"===t[e+r+1][0])&&t[e+r+1][1]<n&&t[e+r+1][3]===t[e][2])return r+1;if(null!==o||"set"!==t[e+r+1][0]&&"insert"!==t[e+r+1][0]||t[e+r+1][1]!==n-(r+1)||void 0!==t[e+r+1][3])if(null===o&&e+r+1<t.length&&"set"===t[e+r+1][0]&&void 0!==t[e+r+1][3])o=[e+r+1,t[e+r+1][1]],r+=1;else {if(null===o||"set"!==t[e+r+1][0]||t[e+r+1][1]!==o[1]+(r+1-o[0])||void 0===t[e+r+1][3])return null;r+=1;}else r+=1;}return null},r=(e,n)=>{let r=0;for(;e+r+1<t.length&&"delete"===t[e+r+1][0]&&t[e+r+1][1]===n-(r+1);)r+=1;return r};let o=0;for(;o<t.length;)if("set"!==t[o][0]&&"insert"!==t[o][0]||void 0!==t[o][3])if(o>0&&"delete"===t[o][0]){const e=t[o][1],n=r(o,e);if("set"===t[o-1][0]&&t[o-1][1]===e-(n+1)&&t[o-1][2]===t[o][2]){const r=["delete",e-(n+1),t[o-1][3],void 0];t.splice(o-1,2),t.splice(o-1+n,0,r),o-=1;}else o+=1;}else o+=1;else {const e=n(o,t[o][1]);null!==e?(t.splice(o+e,1,["insert",t[o+e][1],t[o+e][2],void 0]),t.splice(o,1)):o+=1;}return t})(e).forEach(e=>{const t=e[1];if("delete"===e[0])return void(f.y.length>t&&f.y.delete(t,1));const n=f.p[t];void 0!==n&&("set"===e[0]?(f.y.length>t&&f.y.delete(t,1),p(n,f.y,t)):"insert"===e[0]&&p(n,f.y,t));});}});});})}(t,c,f),d=function(e,t){const o=o=>{o.forEach(o=>{const s=a(t,e,o.path);if(s.y instanceof YMap)o.changes.keys.forEach((e,t)=>{"delete"===e.action?delete s.p[t]:u(s.y.get(t),s.p,t);});else if(s.y instanceof YArray){if(r(s.p,l(s.y)))return;let e=0;o.changes.delta.forEach(t=>{t.retain&&(e+=t.retain),t.delete&&s.p.splice(e,t.delete),t.insert&&(Array.isArray(t.insert)?t.insert.forEach((t,n)=>{u(t,s.p,e+n);}):u(t.insert,s.p,e),e+=t.insert.length);});}});};return e.observeDeep(o),()=>{e.unobserveDeep(o);}}(c,t);return ()=>{y(),d();}}function p(e,t,r){const o=c(e);void 0!==o||"production"==="production"?t instanceof YMap&&"string"==typeof r?t.set(r,o):t instanceof YArray&&"number"==typeof r&&t.insert(r,[o]):console.warn("unsupported p type",e);}function u(e,t,n){o(t)&&"string"==typeof n?t[n]=l(e):s(t)&&"number"==typeof n&&t.splice(n,0,l(e));}
11530
+ /* eslint @typescript-eslint/no-explicit-any: "off" */
11531
+ const isProxyObject = (x) => typeof x === 'object' && x !== null && getVersion(x) !== undefined;
11532
+ const isProxyArray = (x) => Array.isArray(x) && getVersion(x) !== undefined;
11533
+ const isPrimitiveMapValue = (v) => v === null ||
11534
+ typeof v === 'string' ||
11535
+ typeof v === 'number' ||
11536
+ typeof v === 'boolean';
11537
+ const transact = (doc, opts, fn) => {
11538
+ if (doc) {
11539
+ doc.transact(fn, opts.transactionOrigin);
11540
+ }
11541
+ else {
11542
+ fn();
11543
+ }
11544
+ };
11545
+ const toYValue = (val) => {
11546
+ if (isProxyArray(val)) {
11547
+ const arr = new YArray();
11548
+ arr.insert(0, val.map(toYValue).filter((v) => v !== undefined && v !== null));
11549
+ return arr;
11550
+ }
11551
+ if (isProxyObject(val)) {
11552
+ const map = new YMap();
11553
+ Object.entries(val).forEach(([key, value]) => {
11554
+ const v = toYValue(value);
11555
+ if (v !== undefined) {
11556
+ map.set(key, v);
11557
+ }
11558
+ });
11559
+ return map;
11560
+ }
11561
+ if (isPrimitiveMapValue(val)) {
11562
+ return val;
11563
+ }
11564
+ return undefined;
11565
+ };
11566
+ const toJSON = (yv) => {
11567
+ if (yv instanceof AbstractType) {
11568
+ return yv.toJSON();
11569
+ }
11570
+ return yv;
11571
+ };
11572
+ const getNestedValues = (p, y, path) => {
11573
+ let pv = p;
11574
+ let yv = y;
11575
+ for (let i = 0; i < path.length; i += 1) {
11576
+ const k = path[i];
11577
+ if (yv instanceof YMap) {
11578
+ // child may already be deleted
11579
+ if (!pv)
11580
+ break;
11581
+ pv = pv[k];
11582
+ yv = yv.get(k);
11583
+ }
11584
+ else if (yv instanceof YArray) {
11585
+ // child may already be deleted
11586
+ if (!pv)
11587
+ break;
11588
+ const index = Number(k);
11589
+ pv = pv[k];
11590
+ yv = yv.get(index);
11591
+ }
11592
+ else {
11593
+ pv = null;
11594
+ yv = null;
11595
+ }
11596
+ }
11597
+ return { p: pv, y: yv };
11598
+ };
11599
+ function bind$1(p, y, opts = {}) {
11600
+ if (isProxyArray(p) && !(y instanceof YArray)) ;
11601
+ if (isProxyObject(p) && !isProxyArray(p) && !(y instanceof YMap)) ;
11602
+ // initialize from y
11603
+ initializeFromY(p, y);
11604
+ // initialize from p
11605
+ initializeFromP(p, y, opts);
11606
+ if (isProxyArray(p) && y instanceof YArray) {
11607
+ p.splice(y.length);
11608
+ }
11609
+ // subscribe p
11610
+ const unsubscribeP = subscribeP(p, y, opts);
11611
+ // subscribe y
11612
+ const unsubscribeY = subscribeY(y, p);
11613
+ return () => {
11614
+ unsubscribeP();
11615
+ unsubscribeY();
11616
+ };
11617
+ }
11618
+ function initializeFromP(p, y, opts) {
11619
+ transact(y.doc, opts, () => {
11620
+ if (isProxyObject(p) && y instanceof YMap) {
11621
+ Object.entries(p).forEach(([k, pv]) => {
11622
+ const yv = y.get(k);
11623
+ if (!deepEqual(pv, toJSON(yv))) {
11624
+ insertPValueToY(pv, y, k);
11625
+ }
11626
+ });
11627
+ }
11628
+ if (isProxyArray(p) && y instanceof YArray) {
11629
+ p.forEach((pv, i) => {
11630
+ const yv = y.get(i);
11631
+ if (!deepEqual(pv, toJSON(yv))) {
11632
+ insertPValueToY(pv, y, i);
11633
+ }
11634
+ });
11635
+ }
11636
+ });
11637
+ }
11638
+ function initializeFromY(p, y) {
11639
+ if (isProxyObject(p) && y instanceof YMap) {
11640
+ y.forEach((yv, k) => {
11641
+ if (!deepEqual(p[k], toJSON(yv))) {
11642
+ p[k] = toJSON(yv);
11643
+ }
11644
+ });
11645
+ }
11646
+ if (isProxyArray(p) && y instanceof YArray) {
11647
+ y.forEach((yv, i) => {
11648
+ if (!deepEqual(p[i], toJSON(yv))) {
11649
+ insertYValueToP(yv, p, i);
11650
+ }
11651
+ });
11652
+ }
11653
+ }
11654
+ function insertPValueToY(pv, y, k) {
11655
+ const yv = toYValue(pv);
11656
+ if (yv === undefined && "production" !== 'production') {
11657
+ console.warn('unsupported p type', pv);
11658
+ return;
11659
+ }
11660
+ if (y instanceof YMap && typeof k === 'string') {
11661
+ y.set(k, yv);
11662
+ }
11663
+ else if (y instanceof YArray && typeof k === 'number') {
11664
+ y.insert(k, [yv]);
11665
+ }
11666
+ }
11667
+ function insertYValueToP(yv, p, k) {
11668
+ if (isProxyObject(p) && typeof k === 'string') {
11669
+ p[k] = toJSON(yv);
11670
+ }
11671
+ else if (isProxyArray(p) && typeof k === 'number') {
11672
+ p.splice(k, 0, toJSON(yv));
11673
+ }
11674
+ }
11675
+ function subscribeP(p, y, opts) {
11676
+ return subscribe(p, (ops) => {
11677
+ transact(y.doc, opts, () => {
11678
+ ops.forEach((op) => {
11679
+ const path = op[1].slice(0, -1);
11680
+ const k = op[1][op[1].length - 1];
11681
+ const parent = getNestedValues(p, y, path);
11682
+ if (parent.y instanceof YMap) {
11683
+ if (op[0] === 'delete') {
11684
+ parent.y.delete(k);
11685
+ }
11686
+ else if (op[0] === 'set') {
11687
+ const pv = parent.p[k];
11688
+ const yv = parent.y.get(k);
11689
+ if (!deepEqual(toJSON(yv), pv)) {
11690
+ insertPValueToY(pv, parent.y, k);
11691
+ }
11692
+ }
11693
+ }
11694
+ else if (parent.y instanceof YArray) {
11695
+ if (deepEqual(toJSON(parent.y), parent.p)) {
11696
+ return;
11697
+ }
11698
+ const arrayOps = parseProxyOps(ops);
11699
+ arrayOps.forEach((aOp) => {
11700
+ const i = aOp[1];
11701
+ if (aOp[0] === 'delete') {
11702
+ if (parent.y.length > i) {
11703
+ parent.y.delete(i, 1);
11704
+ }
11705
+ return;
11706
+ }
11707
+ const pv = parent.p[i];
11708
+ if (pv === undefined) {
11709
+ return;
11710
+ }
11711
+ if (aOp[0] === 'set') {
11712
+ if (parent.y.length > i) {
11713
+ parent.y.delete(i, 1);
11714
+ }
11715
+ insertPValueToY(pv, parent.y, i);
11716
+ }
11717
+ else if (aOp[0] === 'insert') {
11718
+ insertPValueToY(pv, parent.y, i);
11719
+ }
11720
+ });
11721
+ }
11722
+ });
11723
+ });
11724
+ });
11725
+ }
11726
+ function subscribeY(y, p) {
11727
+ const observer = (events) => {
11728
+ events.forEach((event) => {
11729
+ const path = event.path;
11730
+ const parent = getNestedValues(p, y, path);
11731
+ if (parent.y instanceof YMap) {
11732
+ event.changes.keys.forEach((item, k) => {
11733
+ if (item.action === 'delete') {
11734
+ delete parent.p[k];
11735
+ }
11736
+ else {
11737
+ const yv = parent.y.get(k);
11738
+ insertYValueToP(yv, parent.p, k);
11739
+ }
11740
+ });
11741
+ }
11742
+ else if (parent.y instanceof YArray) {
11743
+ if (deepEqual(parent.p, toJSON(parent.y))) {
11744
+ return;
11745
+ }
11746
+ let retain = 0;
11747
+ event.changes.delta.forEach((item) => {
11748
+ if (item.retain) {
11749
+ retain += item.retain;
11750
+ }
11751
+ if (item.delete) {
11752
+ parent.p.splice(retain, item.delete);
11753
+ }
11754
+ if (item.insert) {
11755
+ if (Array.isArray(item.insert)) {
11756
+ item.insert.forEach((yv, i) => {
11757
+ insertYValueToP(yv, parent.p, retain + i);
11758
+ });
11759
+ }
11760
+ else {
11761
+ insertYValueToP(item.insert, parent.p, retain);
11762
+ }
11763
+ retain += item.insert.length;
11764
+ }
11765
+ });
11766
+ }
11767
+ });
11768
+ };
11769
+ y.observeDeep(observer);
11770
+ return () => {
11771
+ y.unobserveDeep(observer);
11772
+ };
11773
+ }
11250
11774
 
11251
11775
  class KokimokiTransaction {
11252
11776
  // private _clones = new Map<
@@ -11267,7 +11791,7 @@ class KokimokiTransaction {
11267
11791
  applyUpdate(docClone, encodeStateAsUpdate(store.doc));
11268
11792
  // Set up proxy
11269
11793
  const proxyClone = proxy();
11270
- const unbindProxy = f(proxyClone, docRoot);
11794
+ const unbindProxy = bind$1(proxyClone, docRoot);
11271
11795
  this._proxies.push(proxyClone);
11272
11796
  this._unbindProxies.push(unbindProxy);
11273
11797
  // Listen for updates
@@ -11413,7 +11937,7 @@ class KokimokiStore {
11413
11937
  // Construct proxy object
11414
11938
  this.proxy = proxy(); //T["defaultValue"];
11415
11939
  // @ts-ignore
11416
- f(this.proxy, this.docRoot);
11940
+ bind$1(this.proxy, this.docRoot);
11417
11941
  // // Create root proxy
11418
11942
  // const store = this;
11419
11943
  // // @ts-ignore