@automerge/automerge-repo-react-hooks 2.5.2 → 2.6.0-subduction.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.
package/dist/index.js CHANGED
@@ -2146,969 +2146,103 @@ const useLocalAwareness = ({
2146
2146
  return [localState, setState];
2147
2147
  };
2148
2148
 
2149
- // Properties of the document root object
2150
- const STATE = Symbol.for("_am_meta"); // symbol used to hide application metadata on automerge objects
2151
- const TRACE = Symbol.for("_am_trace"); // used for debugging
2152
- const OBJECT_ID = Symbol.for("_am_objectId"); // symbol used to hide the object id on automerge objects
2153
- const IS_PROXY = Symbol.for("_am_isProxy"); // symbol used to test if the document is a proxy object
2154
- const CLEAR_CACHE = Symbol.for("_am_clearCache"); // symbol used to tell a proxy object to clear its cache
2155
- const UINT = Symbol.for("_am_uint");
2156
- const INT = Symbol.for("_am_int");
2157
- const F64 = Symbol.for("_am_f64");
2158
- const COUNTER = Symbol.for("_am_counter");
2159
- const IMMUTABLE_STRING = Symbol.for("_am_immutableString");
2149
+ BigInt("9223372036854775807"); // 2n ** 63n - 1n;
2160
2150
 
2161
- /**
2162
- * The most basic CRDT: an integer value that can be changed only by
2163
- * incrementing and decrementing. Since addition of integers is commutative,
2164
- * the value trivially converges.
2165
- */
2166
- class Counter {
2167
- constructor(value) {
2168
- this.value = value || 0;
2169
- Reflect.defineProperty(this, COUNTER, { value: true });
2170
- }
2171
- /**
2172
- * A peculiar JavaScript language feature from its early days: if the object
2173
- * `x` has a `valueOf()` method that returns a number, you can use numerical
2174
- * operators on the object `x` directly, such as `x + 1` or `x < 4`.
2175
- * This method is also called when coercing a value to a string by
2176
- * concatenating it with another string, as in `x + ''`.
2177
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf
2178
- */
2179
- valueOf() {
2180
- return this.value;
2151
+ let wasm;
2152
+
2153
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
2154
+
2155
+ cachedTextDecoder.decode();
2156
+
2157
+ const cachedTextEncoder = new TextEncoder();
2158
+
2159
+ if (!('encodeInto' in cachedTextEncoder)) {
2160
+ cachedTextEncoder.encodeInto = function (arg, view) {
2161
+ const buf = cachedTextEncoder.encode(arg);
2162
+ view.set(buf);
2163
+ return {
2164
+ read: arg.length,
2165
+ written: buf.length
2166
+ };
2167
+ };
2168
+ }
2169
+
2170
+ function takeFromExternrefTable0(idx) {
2171
+ const value = wasm.__wbindgen_export_4.get(idx);
2172
+ wasm.__externref_table_dealloc(idx);
2173
+ return value;
2174
+ }
2175
+
2176
+ (typeof FinalizationRegistry === 'undefined')
2177
+ ? { }
2178
+ : new FinalizationRegistry(ptr => wasm.__wbg_automerge_free(ptr >>> 0, 1));
2179
+
2180
+ const SyncStateFinalization = (typeof FinalizationRegistry === 'undefined')
2181
+ ? { register: () => {}, unregister: () => {} }
2182
+ : new FinalizationRegistry(ptr => wasm.__wbg_syncstate_free(ptr >>> 0, 1));
2183
+
2184
+ class SyncState {
2185
+
2186
+ static __wrap(ptr) {
2187
+ ptr = ptr >>> 0;
2188
+ const obj = Object.create(SyncState.prototype);
2189
+ obj.__wbg_ptr = ptr;
2190
+ SyncStateFinalization.register(obj, obj.__wbg_ptr, obj);
2191
+ return obj;
2181
2192
  }
2182
- /**
2183
- * Returns the counter value as a decimal string. If `x` is a counter object,
2184
- * this method is called e.g. when you do `['value: ', x].join('')` or when
2185
- * you use string interpolation: `value: ${x}`.
2186
- */
2187
- toString() {
2188
- return this.valueOf().toString();
2193
+
2194
+ __destroy_into_raw() {
2195
+ const ptr = this.__wbg_ptr;
2196
+ this.__wbg_ptr = 0;
2197
+ SyncStateFinalization.unregister(this);
2198
+ return ptr;
2189
2199
  }
2190
- /**
2191
- * Returns the counter value, so that a JSON serialization of an Automerge
2192
- * document represents the counter simply as an integer.
2193
- */
2194
- toJSON() {
2195
- return this.value;
2200
+
2201
+ free() {
2202
+ const ptr = this.__destroy_into_raw();
2203
+ wasm.__wbg_syncstate_free(ptr, 0);
2196
2204
  }
2197
2205
  /**
2198
- * Increases the value of the counter by `delta`. If `delta` is not given,
2199
- * increases the value of the counter by 1.
2200
- *
2201
- * Will throw an error if used outside of a change callback.
2206
+ * @returns {Heads}
2202
2207
  */
2203
- increment(_delta) {
2204
- throw new Error("Counters should not be incremented outside of a change callback");
2208
+ get sharedHeads() {
2209
+ const ret = wasm.syncstate_sharedHeads(this.__wbg_ptr);
2210
+ return ret;
2205
2211
  }
2206
2212
  /**
2207
- * Decreases the value of the counter by `delta`. If `delta` is not given,
2208
- * decreases the value of the counter by 1.
2209
- *
2210
- * Will throw an error if used outside of a change callback.
2213
+ * @returns {Heads}
2211
2214
  */
2212
- decrement(_delta) {
2213
- throw new Error("Counters should not be decremented outside of a change callback");
2214
- }
2215
- }
2216
- /**
2217
- * An instance of this class is used when a counter is accessed within a change
2218
- * callback.
2219
- */
2220
- class WriteableCounter extends Counter {
2221
- constructor(value, context, path, objectId, key) {
2222
- super(value);
2223
- this.context = context;
2224
- this.path = path;
2225
- this.objectId = objectId;
2226
- this.key = key;
2215
+ get lastSentHeads() {
2216
+ const ret = wasm.syncstate_lastSentHeads(this.__wbg_ptr);
2217
+ return ret;
2227
2218
  }
2228
2219
  /**
2229
- * Increases the value of the counter by `delta`. If `delta` is not given,
2230
- * increases the value of the counter by 1.
2220
+ * @param {Heads} heads
2231
2221
  */
2232
- increment(delta) {
2233
- delta = typeof delta === "number" ? delta : 1;
2234
- this.context.increment(this.objectId, this.key, delta);
2235
- this.value += delta;
2236
- return this.value;
2222
+ set lastSentHeads(heads) {
2223
+ const ret = wasm.syncstate_set_lastSentHeads(this.__wbg_ptr, heads);
2224
+ if (ret[1]) {
2225
+ throw takeFromExternrefTable0(ret[0]);
2226
+ }
2237
2227
  }
2238
2228
  /**
2239
- * Decreases the value of the counter by `delta`. If `delta` is not given,
2240
- * decreases the value of the counter by 1.
2229
+ * @param {Heads} hashes
2241
2230
  */
2242
- decrement(delta) {
2243
- return this.increment(typeof delta === "number" ? -delta : -1);
2244
- }
2245
- }
2246
- /**
2247
- * Returns an instance of `WriteableCounter` for use in a change callback.
2248
- * `context` is the proxy context that keeps track of the mutations.
2249
- * `objectId` is the ID of the object containing the counter, and `key` is
2250
- * the property name (key in map, or index in list) where the counter is
2251
- * located.
2252
- */
2253
- function getWriteableCounter(value, context, path, objectId, key) {
2254
- return new WriteableCounter(value, context, path, objectId, key);
2255
- }
2256
- //module.exports = { Counter, getWriteableCounter }
2257
-
2258
- var _a;
2259
- class ImmutableString {
2260
- constructor(val) {
2261
- // Used to detect whether a value is a ImmutableString object rather than using an instanceof check
2262
- this[_a] = true;
2263
- this.val = val;
2231
+ set sentHashes(hashes) {
2232
+ const ret = wasm.syncstate_set_sentHashes(this.__wbg_ptr, hashes);
2233
+ if (ret[1]) {
2234
+ throw takeFromExternrefTable0(ret[0]);
2235
+ }
2264
2236
  }
2265
2237
  /**
2266
- * Returns the content of the ImmutableString object as a simple string
2238
+ * @returns {SyncState}
2267
2239
  */
2268
- toString() {
2269
- return this.val;
2270
- }
2271
- toJSON() {
2272
- return this.val;
2240
+ clone() {
2241
+ const ret = wasm.syncstate_clone(this.__wbg_ptr);
2242
+ return SyncState.__wrap(ret);
2273
2243
  }
2274
2244
  }
2275
- _a = IMMUTABLE_STRING;
2276
-
2277
- function parseListIndex(key) {
2278
- if (typeof key === "string" && /^[0-9]+$/.test(key))
2279
- key = parseInt(key, 10);
2280
- if (typeof key !== "number") {
2281
- return key;
2282
- }
2283
- if (key < 0 || isNaN(key) || key === Infinity || key === -Infinity) {
2284
- throw new RangeError("A list index must be positive, but you passed " + key);
2285
- }
2286
- return key;
2287
- }
2288
- function valueAt(target, prop) {
2289
- const { context, objectId, path } = target;
2290
- const value = context.getWithType(objectId, prop);
2291
- if (value === null) {
2292
- return;
2293
- }
2294
- const datatype = value[0];
2295
- const val = value[1];
2296
- switch (datatype) {
2297
- case undefined:
2298
- return;
2299
- case "map":
2300
- return mapProxy(context, val, [...path, prop]);
2301
- case "list":
2302
- return listProxy(context, val, [...path, prop]);
2303
- case "text":
2304
- return context.text(val);
2305
- case "str":
2306
- return new ImmutableString(val);
2307
- case "uint":
2308
- return val;
2309
- case "int":
2310
- return val;
2311
- case "f64":
2312
- return val;
2313
- case "boolean":
2314
- return val;
2315
- case "null":
2316
- return null;
2317
- case "bytes":
2318
- return val;
2319
- case "timestamp":
2320
- return val;
2321
- case "counter": {
2322
- const counter = getWriteableCounter(val, context, path, objectId, prop);
2323
- return counter;
2324
- }
2325
- default:
2326
- throw RangeError(`datatype ${datatype} unimplemented`);
2327
- }
2328
- }
2329
- function import_value(value, path, context) {
2330
- const type = typeof value;
2331
- switch (type) {
2332
- case "object":
2333
- if (value == null) {
2334
- return [null, "null"];
2335
- }
2336
- else if (value[UINT]) {
2337
- return [value.value, "uint"];
2338
- }
2339
- else if (value[INT]) {
2340
- return [value.value, "int"];
2341
- }
2342
- else if (value[F64]) {
2343
- return [value.value, "f64"];
2344
- }
2345
- else if (value[COUNTER]) {
2346
- return [value.value, "counter"];
2347
- }
2348
- else if (value instanceof Date) {
2349
- return [value.getTime(), "timestamp"];
2350
- }
2351
- else if (isImmutableString(value)) {
2352
- return [value.toString(), "str"];
2353
- }
2354
- else if (value instanceof Uint8Array) {
2355
- return [value, "bytes"];
2356
- }
2357
- else if (value instanceof Array) {
2358
- return [value, "list"];
2359
- }
2360
- else if (Object.prototype.toString.call(value) === "[object Object]") {
2361
- return [value, "map"];
2362
- }
2363
- else if (isSameDocument(value, context)) {
2364
- throw new RangeError("Cannot create a reference to an existing document object");
2365
- }
2366
- else {
2367
- throw new RangeError(`Cannot assign unknown object: ${value}`);
2368
- }
2369
- case "boolean":
2370
- return [value, "boolean"];
2371
- case "number":
2372
- if (Number.isInteger(value)) {
2373
- return [value, "int"];
2374
- }
2375
- else {
2376
- return [value, "f64"];
2377
- }
2378
- case "string":
2379
- return [value, "text"];
2380
- case "undefined":
2381
- throw new RangeError([
2382
- `Cannot assign undefined value at ${printPath(path)}, `,
2383
- "because `undefined` is not a valid JSON data type. ",
2384
- "You might consider setting the property's value to `null`, ",
2385
- "or using `delete` to remove it altogether.",
2386
- ].join(""));
2387
- default:
2388
- throw new RangeError([
2389
- `Cannot assign ${type} value at ${printPath(path)}. `,
2390
- `All JSON primitive datatypes (object, array, string, number, boolean, null) `,
2391
- `are supported in an Automerge document; ${type} values are not. `,
2392
- ].join(""));
2393
- }
2394
- }
2395
- // When we assign a value to a property in a proxy we recursively walk through
2396
- // the value we are assigning and copy it into the document. This is generally
2397
- // desirable behaviour. However, a very common bug is to accidentally assign a
2398
- // value which is already in the document to another key within the same
2399
- // document, this often leads to surprising behaviour where users expected to
2400
- // _move_ the object, but it is instead copied. To avoid this we check if the
2401
- // value is from the same document and if it is we throw an error, this means
2402
- // we require an explicit Object.assign call to copy the object, thus avoiding
2403
- // the footgun
2404
- function isSameDocument(val, context) {
2405
- var _b, _c;
2406
- // Date is technically an object, but immutable, so allowing people to assign
2407
- // a date from one place in the document to another place in the document is
2408
- // not likely to be a bug
2409
- if (val instanceof Date) {
2410
- return false;
2411
- }
2412
- // this depends on __wbg_ptr being the wasm pointer
2413
- // a new version of wasm-bindgen will break this
2414
- // but the tests should expose the break
2415
- if (val && ((_c = (_b = val[STATE]) === null || _b === void 0 ? void 0 : _b.handle) === null || _c === void 0 ? void 0 : _c.__wbg_ptr) === context.__wbg_ptr) {
2416
- return true;
2417
- }
2418
- return false;
2419
- }
2420
- const MapHandler = {
2421
- get(target, key) {
2422
- const { context, objectId, cache } = target;
2423
- if (key === Symbol.toStringTag) {
2424
- return target[Symbol.toStringTag];
2425
- }
2426
- if (key === OBJECT_ID)
2427
- return objectId;
2428
- if (key === IS_PROXY)
2429
- return true;
2430
- if (key === TRACE)
2431
- return target.trace;
2432
- if (key === STATE)
2433
- return { handle: context };
2434
- if (!cache[key]) {
2435
- cache[key] = valueAt(target, key);
2436
- }
2437
- return cache[key];
2438
- },
2439
- set(target, key, val) {
2440
- const { context, objectId, path } = target;
2441
- target.cache = {}; // reset cache on set
2442
- if (isSameDocument(val, context)) {
2443
- throw new RangeError("Cannot create a reference to an existing document object");
2444
- }
2445
- if (key === TRACE) {
2446
- target.trace = val;
2447
- return true;
2448
- }
2449
- if (key === CLEAR_CACHE) {
2450
- return true;
2451
- }
2452
- const [value, datatype] = import_value(val, [...path, key], context);
2453
- switch (datatype) {
2454
- case "list": {
2455
- const list = context.putObject(objectId, key, []);
2456
- const proxyList = listProxy(context, list, [...path, key]);
2457
- for (let i = 0; i < value.length; i++) {
2458
- proxyList[i] = value[i];
2459
- }
2460
- break;
2461
- }
2462
- case "text": {
2463
- context.putObject(objectId, key, value);
2464
- break;
2465
- }
2466
- case "map": {
2467
- const map = context.putObject(objectId, key, {});
2468
- const proxyMap = mapProxy(context, map, [...path, key]);
2469
- for (const key in value) {
2470
- proxyMap[key] = value[key];
2471
- }
2472
- break;
2473
- }
2474
- default:
2475
- context.put(objectId, key, value, datatype);
2476
- }
2477
- return true;
2478
- },
2479
- deleteProperty(target, key) {
2480
- const { context, objectId } = target;
2481
- target.cache = {}; // reset cache on delete
2482
- context.delete(objectId, key);
2483
- return true;
2484
- },
2485
- has(target, key) {
2486
- const value = this.get(target, key);
2487
- return value !== undefined;
2488
- },
2489
- getOwnPropertyDescriptor(target, key) {
2490
- // const { context, objectId } = target
2491
- const value = this.get(target, key);
2492
- if (typeof value !== "undefined") {
2493
- return {
2494
- configurable: true,
2495
- enumerable: true,
2496
- value,
2497
- };
2498
- }
2499
- },
2500
- ownKeys(target) {
2501
- const { context, objectId } = target;
2502
- // FIXME - this is a tmp workaround until fix the dupe key bug in keys()
2503
- const keys = context.keys(objectId);
2504
- return [...new Set(keys)];
2505
- },
2506
- };
2507
- const ListHandler = {
2508
- get(target, index) {
2509
- const { context, objectId } = target;
2510
- index = parseListIndex(index);
2511
- if (index === Symbol.hasInstance) {
2512
- return (instance) => {
2513
- return Array.isArray(instance);
2514
- };
2515
- }
2516
- if (index === Symbol.toStringTag) {
2517
- return target[Symbol.toStringTag];
2518
- }
2519
- if (index === OBJECT_ID)
2520
- return objectId;
2521
- if (index === IS_PROXY)
2522
- return true;
2523
- if (index === TRACE)
2524
- return target.trace;
2525
- if (index === STATE)
2526
- return { handle: context };
2527
- if (index === "length")
2528
- return context.length(objectId);
2529
- if (typeof index === "number") {
2530
- return valueAt(target, index);
2531
- }
2532
- else {
2533
- return listMethods(target)[index];
2534
- }
2535
- },
2536
- set(target, index, val) {
2537
- const { context, objectId, path } = target;
2538
- index = parseListIndex(index);
2539
- if (isSameDocument(val, context)) {
2540
- throw new RangeError("Cannot create a reference to an existing document object");
2541
- }
2542
- if (index === CLEAR_CACHE) {
2543
- return true;
2544
- }
2545
- if (index === TRACE) {
2546
- target.trace = val;
2547
- return true;
2548
- }
2549
- if (typeof index == "string") {
2550
- throw new RangeError("list index must be a number");
2551
- }
2552
- const [value, datatype] = import_value(val, [...path, index], context);
2553
- switch (datatype) {
2554
- case "list": {
2555
- let list;
2556
- if (index >= context.length(objectId)) {
2557
- list = context.insertObject(objectId, index, []);
2558
- }
2559
- else {
2560
- list = context.putObject(objectId, index, []);
2561
- }
2562
- const proxyList = listProxy(context, list, [...path, index]);
2563
- proxyList.splice(0, 0, ...value);
2564
- break;
2565
- }
2566
- case "text": {
2567
- if (index >= context.length(objectId)) {
2568
- context.insertObject(objectId, index, value);
2569
- }
2570
- else {
2571
- context.putObject(objectId, index, value);
2572
- }
2573
- break;
2574
- }
2575
- case "map": {
2576
- let map;
2577
- if (index >= context.length(objectId)) {
2578
- map = context.insertObject(objectId, index, {});
2579
- }
2580
- else {
2581
- map = context.putObject(objectId, index, {});
2582
- }
2583
- const proxyMap = mapProxy(context, map, [...path, index]);
2584
- for (const key in value) {
2585
- proxyMap[key] = value[key];
2586
- }
2587
- break;
2588
- }
2589
- default:
2590
- if (index >= context.length(objectId)) {
2591
- context.insert(objectId, index, value, datatype);
2592
- }
2593
- else {
2594
- context.put(objectId, index, value, datatype);
2595
- }
2596
- }
2597
- return true;
2598
- },
2599
- deleteProperty(target, index) {
2600
- const { context, objectId } = target;
2601
- index = parseListIndex(index);
2602
- const elem = context.get(objectId, index);
2603
- if (elem != null && elem[0] == "counter") {
2604
- throw new TypeError("Unsupported operation: deleting a counter from a list");
2605
- }
2606
- context.delete(objectId, index);
2607
- return true;
2608
- },
2609
- has(target, index) {
2610
- const { context, objectId } = target;
2611
- index = parseListIndex(index);
2612
- if (typeof index === "number") {
2613
- return index < context.length(objectId);
2614
- }
2615
- return index === "length";
2616
- },
2617
- getOwnPropertyDescriptor(target, index) {
2618
- const { context, objectId } = target;
2619
- if (index === "length")
2620
- return { writable: true, value: context.length(objectId) };
2621
- if (index === OBJECT_ID)
2622
- return { configurable: false, enumerable: false, value: objectId };
2623
- index = parseListIndex(index);
2624
- const value = valueAt(target, index);
2625
- return { configurable: true, enumerable: true, value };
2626
- },
2627
- getPrototypeOf(target) {
2628
- return Object.getPrototypeOf(target);
2629
- },
2630
- ownKeys( /*target*/) {
2631
- const keys = [];
2632
- // uncommenting this causes assert.deepEqual() to fail when comparing to a pojo array
2633
- // but not uncommenting it causes for (i in list) {} to not enumerate values properly
2634
- //const {context, objectId } = target
2635
- //for (let i = 0; i < target.context.length(objectId); i++) { keys.push(i.toString()) }
2636
- keys.push("length");
2637
- return keys;
2638
- },
2639
- };
2640
- Object.assign({}, ListHandler, {
2641
- get(target, index) {
2642
- const { context, objectId } = target;
2643
- index = parseListIndex(index);
2644
- if (index === Symbol.hasInstance) {
2645
- return (instance) => {
2646
- return Array.isArray(instance);
2647
- };
2648
- }
2649
- if (index === Symbol.toStringTag) {
2650
- return target[Symbol.toStringTag];
2651
- }
2652
- if (index === OBJECT_ID)
2653
- return objectId;
2654
- if (index === IS_PROXY)
2655
- return true;
2656
- if (index === TRACE)
2657
- return target.trace;
2658
- if (index === STATE)
2659
- return { handle: context };
2660
- if (index === "length")
2661
- return context.length(objectId);
2662
- if (typeof index === "number") {
2663
- return valueAt(target, index);
2664
- }
2665
- else {
2666
- return textMethods(target)[index] || listMethods(target)[index];
2667
- }
2668
- },
2669
- getPrototypeOf( /*target*/) {
2670
- return Object.getPrototypeOf(new Text());
2671
- },
2672
- });
2673
- function mapProxy(context, objectId, path) {
2674
- const target = {
2675
- context,
2676
- objectId,
2677
- path: path || [],
2678
- cache: {},
2679
- };
2680
- const proxied = {};
2681
- Object.assign(proxied, target);
2682
- const result = new Proxy(proxied, MapHandler);
2683
- // conversion through unknown is necessary because the types are so different
2684
- return result;
2685
- }
2686
- function listProxy(context, objectId, path) {
2687
- const target = {
2688
- context,
2689
- objectId,
2690
- path: path || [],
2691
- cache: {},
2692
- };
2693
- const proxied = [];
2694
- Object.assign(proxied, target);
2695
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2696
- // @ts-ignore
2697
- return new Proxy(proxied, ListHandler);
2698
- }
2699
- function listMethods(target) {
2700
- const { context, objectId, path } = target;
2701
- const methods = {
2702
- at(index) {
2703
- return valueAt(target, index);
2704
- },
2705
- deleteAt(index, numDelete) {
2706
- if (typeof numDelete === "number") {
2707
- context.splice(objectId, index, numDelete);
2708
- }
2709
- else {
2710
- context.delete(objectId, index);
2711
- }
2712
- return this;
2713
- },
2714
- fill(val, start, end) {
2715
- const [value, datatype] = import_value(val, [...path, start], context);
2716
- const length = context.length(objectId);
2717
- start = parseListIndex(start || 0);
2718
- end = parseListIndex(end || length);
2719
- for (let i = start; i < Math.min(end, length); i++) {
2720
- if (datatype === "list" || datatype === "map") {
2721
- context.putObject(objectId, i, value);
2722
- }
2723
- else if (datatype === "text") {
2724
- context.putObject(objectId, i, value);
2725
- }
2726
- else {
2727
- context.put(objectId, i, value, datatype);
2728
- }
2729
- }
2730
- return this;
2731
- },
2732
- indexOf(searchElement, start = 0) {
2733
- const length = context.length(objectId);
2734
- for (let i = start; i < length; i++) {
2735
- const valueWithType = context.getWithType(objectId, i);
2736
- if (!valueWithType) {
2737
- continue;
2738
- }
2739
- const [valType, value] = valueWithType;
2740
- // Either the target element is an object, and we return if we have found
2741
- // the same object or it is a primitive value and we return if it matches
2742
- // the current value
2743
- const isObject = ["map", "list", "text"].includes(valType);
2744
- if (!isObject) {
2745
- // If the element is not an object, then check if the value is equal to the target
2746
- if (value === searchElement) {
2747
- return i;
2748
- }
2749
- else {
2750
- continue;
2751
- }
2752
- }
2753
- // if it's an object, but the type of the search element is a string, then we
2754
- // need to check if the object is a text object with the same value as the search element
2755
- if (valType === "text" && typeof searchElement === "string") {
2756
- if (searchElement === valueAt(target, i)) {
2757
- return i;
2758
- }
2759
- }
2760
- // The only possible match now is if the searchElement is an object already in the
2761
- // automerge document with the same object ID as the value
2762
- if (searchElement[OBJECT_ID] === value) {
2763
- return i;
2764
- }
2765
- }
2766
- return -1;
2767
- },
2768
- insertAt(index, ...values) {
2769
- this.splice(index, 0, ...values);
2770
- return this;
2771
- },
2772
- pop() {
2773
- const length = context.length(objectId);
2774
- if (length == 0) {
2775
- return undefined;
2776
- }
2777
- const last = valueAt(target, length - 1);
2778
- context.delete(objectId, length - 1);
2779
- return last;
2780
- },
2781
- push(...values) {
2782
- const len = context.length(objectId);
2783
- this.splice(len, 0, ...values);
2784
- return context.length(objectId);
2785
- },
2786
- shift() {
2787
- if (context.length(objectId) == 0)
2788
- return;
2789
- const first = valueAt(target, 0);
2790
- context.delete(objectId, 0);
2791
- return first;
2792
- },
2793
- splice(index, del, ...vals) {
2794
- index = parseListIndex(index);
2795
- // if del is undefined, delete until the end of the list
2796
- if (typeof del !== "number") {
2797
- del = context.length(objectId) - index;
2798
- }
2799
- del = parseListIndex(del);
2800
- for (const val of vals) {
2801
- if (isSameDocument(val, context)) {
2802
- throw new RangeError("Cannot create a reference to an existing document object");
2803
- }
2804
- }
2805
- const result = [];
2806
- for (let i = 0; i < del; i++) {
2807
- const value = valueAt(target, index);
2808
- if (value !== undefined) {
2809
- result.push(value);
2810
- }
2811
- context.delete(objectId, index);
2812
- }
2813
- const values = vals.map((val, index) => {
2814
- try {
2815
- return import_value(val, [...path], context);
2816
- }
2817
- catch (e) {
2818
- if (e instanceof RangeError) {
2819
- throw new RangeError(`${e.message} (at index ${index} in the input)`);
2820
- }
2821
- else {
2822
- throw e;
2823
- }
2824
- }
2825
- });
2826
- for (const [value, datatype] of values) {
2827
- switch (datatype) {
2828
- case "list": {
2829
- const list = context.insertObject(objectId, index, []);
2830
- const proxyList = listProxy(context, list, [...path, index]);
2831
- proxyList.splice(0, 0, ...value);
2832
- break;
2833
- }
2834
- case "text": {
2835
- context.insertObject(objectId, index, value);
2836
- break;
2837
- }
2838
- case "map": {
2839
- const map = context.insertObject(objectId, index, {});
2840
- const proxyMap = mapProxy(context, map, [...path, index]);
2841
- for (const key in value) {
2842
- proxyMap[key] = value[key];
2843
- }
2844
- break;
2845
- }
2846
- default:
2847
- context.insert(objectId, index, value, datatype);
2848
- }
2849
- index += 1;
2850
- }
2851
- return result;
2852
- },
2853
- unshift(...values) {
2854
- this.splice(0, 0, ...values);
2855
- return context.length(objectId);
2856
- },
2857
- entries() {
2858
- let i = 0;
2859
- const iterator = {
2860
- next: () => {
2861
- const value = valueAt(target, i);
2862
- if (value === undefined) {
2863
- return { value: undefined, done: true };
2864
- }
2865
- else {
2866
- return { value: [i++, value], done: false };
2867
- }
2868
- },
2869
- [Symbol.iterator]() {
2870
- return this;
2871
- },
2872
- };
2873
- return iterator;
2874
- },
2875
- keys() {
2876
- let i = 0;
2877
- const len = context.length(objectId);
2878
- const iterator = {
2879
- next: () => {
2880
- if (i < len) {
2881
- return { value: i++, done: false };
2882
- }
2883
- return { value: undefined, done: true };
2884
- },
2885
- [Symbol.iterator]() {
2886
- return this;
2887
- },
2888
- };
2889
- return iterator;
2890
- },
2891
- values() {
2892
- let i = 0;
2893
- const iterator = {
2894
- next: () => {
2895
- const value = valueAt(target, i++);
2896
- if (value === undefined) {
2897
- return { value: undefined, done: true };
2898
- }
2899
- else {
2900
- return { value, done: false };
2901
- }
2902
- },
2903
- [Symbol.iterator]() {
2904
- return this;
2905
- },
2906
- };
2907
- return iterator;
2908
- },
2909
- toArray() {
2910
- const list = [];
2911
- let value;
2912
- do {
2913
- value = valueAt(target, list.length);
2914
- if (value !== undefined) {
2915
- list.push(value);
2916
- }
2917
- } while (value !== undefined);
2918
- return list;
2919
- },
2920
- map(f) {
2921
- return this.toArray().map(f);
2922
- },
2923
- toString() {
2924
- return this.toArray().toString();
2925
- },
2926
- toLocaleString() {
2927
- return this.toArray().toLocaleString();
2928
- },
2929
- forEach(f) {
2930
- return this.toArray().forEach(f);
2931
- },
2932
- // todo: real concat function is different
2933
- concat(other) {
2934
- return this.toArray().concat(other);
2935
- },
2936
- every(f) {
2937
- return this.toArray().every(f);
2938
- },
2939
- filter(f) {
2940
- return this.toArray().filter(f);
2941
- },
2942
- find(f) {
2943
- let index = 0;
2944
- for (const v of this) {
2945
- if (f(v, index)) {
2946
- return v;
2947
- }
2948
- index += 1;
2949
- }
2950
- },
2951
- findIndex(f) {
2952
- let index = 0;
2953
- for (const v of this) {
2954
- if (f(v, index)) {
2955
- return index;
2956
- }
2957
- index += 1;
2958
- }
2959
- return -1;
2960
- },
2961
- includes(elem) {
2962
- return this.find(e => e === elem) !== undefined;
2963
- },
2964
- join(sep) {
2965
- return this.toArray().join(sep);
2966
- },
2967
- reduce(f, initialValue) {
2968
- return this.toArray().reduce(f, initialValue);
2969
- },
2970
- reduceRight(f, initialValue) {
2971
- return this.toArray().reduceRight(f, initialValue);
2972
- },
2973
- lastIndexOf(search, fromIndex = +Infinity) {
2974
- // this can be faster
2975
- return this.toArray().lastIndexOf(search, fromIndex);
2976
- },
2977
- slice(index, num) {
2978
- return this.toArray().slice(index, num);
2979
- },
2980
- some(f) {
2981
- let index = 0;
2982
- for (const v of this) {
2983
- if (f(v, index)) {
2984
- return true;
2985
- }
2986
- index += 1;
2987
- }
2988
- return false;
2989
- },
2990
- [Symbol.iterator]: function* () {
2991
- let i = 0;
2992
- let value = valueAt(target, i);
2993
- while (value !== undefined) {
2994
- yield value;
2995
- i += 1;
2996
- value = valueAt(target, i);
2997
- }
2998
- },
2999
- };
3000
- return methods;
3001
- }
3002
- function textMethods(target) {
3003
- const { context, objectId } = target;
3004
- const methods = {
3005
- set(index, value) {
3006
- return (this[index] = value);
3007
- },
3008
- get(index) {
3009
- return this[index];
3010
- },
3011
- toString() {
3012
- return context.text(objectId).replace(//g, "");
3013
- },
3014
- toSpans() {
3015
- const spans = [];
3016
- let chars = "";
3017
- const length = context.length(objectId);
3018
- for (let i = 0; i < length; i++) {
3019
- const value = this[i];
3020
- if (typeof value === "string") {
3021
- chars += value;
3022
- }
3023
- else {
3024
- if (chars.length > 0) {
3025
- spans.push(chars);
3026
- chars = "";
3027
- }
3028
- spans.push(value);
3029
- }
3030
- }
3031
- if (chars.length > 0) {
3032
- spans.push(chars);
3033
- }
3034
- return spans;
3035
- },
3036
- toJSON() {
3037
- return this.toString();
3038
- },
3039
- indexOf(o, start = 0) {
3040
- const text = context.text(objectId);
3041
- return text.indexOf(o, start);
3042
- },
3043
- insertAt(index, ...values) {
3044
- if (values.every(v => typeof v === "string")) {
3045
- context.splice(objectId, index, 0, values.join(""));
3046
- }
3047
- else {
3048
- listMethods(target).insertAt(index, ...values);
3049
- }
3050
- },
3051
- };
3052
- return methods;
3053
- }
3054
- function printPath(path) {
3055
- // print the path as a json pointer
3056
- const jsonPointerComponents = path.map(component => {
3057
- // if its a number just turn it into a string
3058
- if (typeof component === "number") {
3059
- return component.toString();
3060
- }
3061
- else if (typeof component === "string") {
3062
- // otherwise we have to escape `/` and `~` characters
3063
- return component.replace(/~/g, "~0").replace(/\//g, "~1");
3064
- }
3065
- });
3066
- if (path.length === 0) {
3067
- return "";
3068
- }
3069
- else {
3070
- return "/" + jsonPointerComponents.join("/");
3071
- }
3072
- }
3073
- /*
3074
- * Check if an object is a {@link ImmutableString}
3075
- */
3076
- function isImmutableString(obj) {
3077
- // We used to determine whether something was a ImmutableString by doing an instanceof check, but
3078
- // this doesn't work if the automerge module is loaded twice somehow. Instead, use the presence
3079
- // of a symbol to determine if something is a ImmutableString
3080
- return (typeof obj === "object" &&
3081
- obj !== null &&
3082
- Object.prototype.hasOwnProperty.call(obj, IMMUTABLE_STRING));
3083
- }
3084
-
3085
- let wasm;
3086
-
3087
- const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
3088
-
3089
- (typeof cachedTextEncoder.encodeInto === 'function'
3090
- ? function (arg, view) {
3091
- return cachedTextEncoder.encodeInto(arg, view);
3092
- }
3093
- : function (arg, view) {
3094
- const buf = cachedTextEncoder.encode(arg);
3095
- view.set(buf);
3096
- return {
3097
- read: arg.length,
3098
- written: buf.length
3099
- };
3100
- });
3101
-
3102
- const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
3103
-
3104
- if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }
3105
- (typeof FinalizationRegistry === 'undefined')
3106
- ? { }
3107
- : new FinalizationRegistry(ptr => wasm.__wbg_automerge_free(ptr >>> 0, 1));
3108
-
3109
- (typeof FinalizationRegistry === 'undefined')
3110
- ? { }
3111
- : new FinalizationRegistry(ptr => wasm.__wbg_syncstate_free(ptr >>> 0, 1));
2245
+ if (Symbol.dispose) SyncState.prototype[Symbol.dispose] = SyncState.prototype.free;
3112
2246
 
3113
2247
  (undefined && undefined.__rest) || function (s, e) {
3114
2248
  var t = {};
@@ -6241,13 +5375,6 @@ const REUSE_BUFFER_MODE = 512;
6241
5375
  const RESET_BUFFER_MODE = 1024;
6242
5376
  const THROW_ON_ITERABLE = 2048;
6243
5377
 
6244
- /**
6245
- * FinalizationRegistry for automatic cleanup of Ref instances.
6246
- * This ensures subscriptions are cleaned up when Refs are garbage collected,
6247
- * even if dispose() is never called.
6248
- */
6249
- new FinalizationRegistry(cleanup => cleanup());
6250
-
6251
5378
  var sha256$1 = {exports: {}};
6252
5379
 
6253
5380
  var sha256 = sha256$1.exports;
@@ -6758,7 +5885,7 @@ class PeerStateView {
6758
5885
  getLastSeenPeer(peers) {
6759
5886
  let freshestLastSeenAt;
6760
5887
  return peers.reduce((freshest, curr) => {
6761
- const lastSeenAt = this.value[curr]?.lastSeenAt;
5888
+ const lastSeenAt = this.value[curr]?.lastActiveAt;
6762
5889
  if (!lastSeenAt) {
6763
5890
  return freshest;
6764
5891
  }
@@ -6848,15 +5975,11 @@ class PeerPresenceInfo {
6848
5975
  * @param peerId
6849
5976
  */
6850
5977
  markSeen(peerId) {
6851
- if (!(peerId in this.#peerStates.value)) {
6852
- // Ignore heartbeats from peers we have not seen before: they will send a snapshot
6853
- return;
6854
- }
6855
5978
  this.#peerStates = new PeerStateView({
6856
5979
  ...this.#peerStates.value,
6857
5980
  [peerId]: {
6858
5981
  ...this.#peerStates.value[peerId],
6859
- lastSeenAt: Date.now(),
5982
+ lastSeen: Date.now(),
6860
5983
  },
6861
5984
  });
6862
5985
  }
@@ -6878,7 +6001,7 @@ class PeerPresenceInfo {
6878
6001
  deviceId,
6879
6002
  userId,
6880
6003
  lastActiveAt: now,
6881
- lastSeenAt: now,
6004
+ lastUpdateAt: now,
6882
6005
  value: {
6883
6006
  ...existingState,
6884
6007
  ...value,
@@ -6902,15 +6025,9 @@ class PeerPresenceInfo {
6902
6025
  */
6903
6026
  prune() {
6904
6027
  const threshold = Date.now() - this.ttl;
6905
- const pruned = [];
6906
- this.#peerStates = new PeerStateView(Object.fromEntries(Object.entries(this.#peerStates.value).filter(([id, state]) => {
6907
- const keep = state.lastSeenAt >= threshold;
6908
- if (!keep) {
6909
- pruned.push(id);
6910
- }
6911
- return keep;
6028
+ this.#peerStates = new PeerStateView(Object.fromEntries(Object.entries(this.#peerStates).filter(([, state]) => {
6029
+ return state.lastActiveAt >= threshold;
6912
6030
  })));
6913
- return pruned;
6914
6031
  }
6915
6032
  /**
6916
6033
  * Get a snapshot of the current peer states
@@ -7151,10 +6268,7 @@ class Presence extends EventEmitter {
7151
6268
  // to minimize variance between peer expiration, since the heartbeat frequency
7152
6269
  // is expected to be several times higher.
7153
6270
  this.#pruningInterval = setInterval(() => {
7154
- const pruned = this.#peers.prune();
7155
- if (pruned.length > 0) {
7156
- this.emit("pruning", { pruned });
7157
- }
6271
+ this.#peers.prune();
7158
6272
  }, this.#heartbeatMs);
7159
6273
  }
7160
6274
  stopPruningPeers() {
@@ -7193,26 +6307,10 @@ function usePresence({
7193
6307
  presence.on("snapshot", () => setPeerStates(presence.getPeerStates()));
7194
6308
  presence.on("update", () => setPeerStates(presence.getPeerStates()));
7195
6309
  presence.on("goodbye", () => setPeerStates(presence.getPeerStates()));
7196
- presence.on("pruning", () => setPeerStates(presence.getPeerStates()));
7197
6310
  return () => {
7198
6311
  presence.stop();
7199
6312
  };
7200
6313
  }, [presence, userId, deviceId, firstInitialState, firstOpts]);
7201
- const start = useCallback(
7202
- (config) => {
7203
- const initialState2 = config?.initialState ?? presence.getLocalState();
7204
- const opts = {
7205
- ...firstOpts.current,
7206
- ...config,
7207
- initialState: initialState2
7208
- };
7209
- presence.start(opts);
7210
- },
7211
- [presence, firstOpts]
7212
- );
7213
- const stop = useCallback(() => {
7214
- presence.stop();
7215
- }, [presence]);
7216
6314
  const update = useCallback(
7217
6315
  (channel, msg) => {
7218
6316
  presence.broadcast(channel, msg);
@@ -7224,9 +6322,7 @@ function usePresence({
7224
6322
  return {
7225
6323
  peerStates,
7226
6324
  localState,
7227
- update,
7228
- start,
7229
- stop
6325
+ update
7230
6326
  };
7231
6327
  }
7232
6328