@ember-data/store 4.13.0-alpha.5 → 4.13.0-alpha.7

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.
@@ -1,10 +1,10 @@
1
1
  import { deprecate, warn, assert } from '@ember/debug';
2
2
  import { dasherize } from '@ember-data/request-utils/string';
3
3
  import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
4
- import { setLogging, getRuntimeConfig } from '@warp-drive/build-config/runtime';
5
4
  import { EnableHydration, SkipCache } from '@warp-drive/core-types/request';
5
+ import { setLogging, getRuntimeConfig } from '@warp-drive/core-types/runtime';
6
6
  import { getOrSetGlobal, peekTransient, setTransient } from '@warp-drive/core-types/-private';
7
- import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_CLIENT_ORIGINATED, DEBUG_IDENTIFIER_BUCKET } from '@warp-drive/core-types/identifier';
7
+ import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_IDENTIFIER_BUCKET, DEBUG_CLIENT_ORIGINATED } from '@warp-drive/core-types/identifier';
8
8
  import { defineSignal, createSignal, subscribe, createArrayTags, addToTransaction, addTransactionCB } from '@ember-data/tracking/-private';
9
9
  import { _backburner } from '@ember/runloop';
10
10
  import { get, set } from '@ember/object';
@@ -669,15 +669,13 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
669
669
  // we enforce immutability in dev
670
670
  // but preserve our ability to do controlled updates to the reference
671
671
  let wrapper = {
672
- get lid() {
673
- return recordIdentifier.lid;
674
- },
672
+ type: recordIdentifier.type,
673
+ lid: recordIdentifier.lid,
675
674
  get id() {
676
675
  return recordIdentifier.id;
677
- },
678
- get type() {
679
- return recordIdentifier.type;
680
- },
676
+ }
677
+ };
678
+ const proto = {
681
679
  get [CACHE_OWNER]() {
682
680
  return recordIdentifier[CACHE_OWNER];
683
681
  },
@@ -689,9 +687,15 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
689
687
  },
690
688
  set [DEBUG_STALE_CACHE_OWNER](value) {
691
689
  recordIdentifier[DEBUG_STALE_CACHE_OWNER] = value;
690
+ },
691
+ get [DEBUG_CLIENT_ORIGINATED]() {
692
+ return clientOriginated;
693
+ },
694
+ get [DEBUG_IDENTIFIER_BUCKET]() {
695
+ return bucket;
692
696
  }
693
697
  };
694
- Object.defineProperty(wrapper, 'toString', {
698
+ Object.defineProperty(proto, 'toString', {
695
699
  enumerable: false,
696
700
  value: () => {
697
701
  const {
@@ -702,7 +706,7 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
702
706
  return `${clientOriginated ? '[CLIENT_ORIGINATED] ' : ''}${String(type)}:${String(id)} (${lid})`;
703
707
  }
704
708
  });
705
- Object.defineProperty(wrapper, 'toJSON', {
709
+ Object.defineProperty(proto, 'toJSON', {
706
710
  enumerable: false,
707
711
  value: () => {
708
712
  const {
@@ -717,8 +721,7 @@ function makeStableRecordIdentifier(recordIdentifier, bucket, clientOriginated)
717
721
  };
718
722
  }
719
723
  });
720
- wrapper[DEBUG_CLIENT_ORIGINATED] = clientOriginated;
721
- wrapper[DEBUG_IDENTIFIER_BUCKET] = bucket;
724
+ Object.setPrototypeOf(wrapper, proto);
722
725
  DEBUG_MAP.set(wrapper, recordIdentifier);
723
726
  wrapper = freeze(wrapper);
724
727
  return wrapper;
@@ -2313,10 +2316,8 @@ class CacheManager {
2313
2316
  * @module @ember-data/store
2314
2317
  */
2315
2318
 
2316
- let tokenId = 0;
2317
- const CacheOperations = new Set(['added', 'removed', 'state', 'updated', 'invalidated']);
2318
2319
  function isCacheOperationValue(value) {
2319
- return CacheOperations.has(value);
2320
+ return value === 'added' || value === 'state' || value === 'updated' || value === 'removed' || value === 'invalidated';
2320
2321
  }
2321
2322
  function runLoopIsFlushing() {
2322
2323
  //@ts-expect-error
@@ -2327,8 +2328,16 @@ function count(label) {
2327
2328
  // eslint-disable-next-line
2328
2329
  globalThis.__WarpDriveMetricCountData[label] = (globalThis.__WarpDriveMetricCountData[label] || 0) + 1;
2329
2330
  }
2330
- function _unsubscribe(tokens, token, cache) {
2331
- const identifier = tokens.get(token);
2331
+ function asInternalToken(token) {
2332
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2333
+ if (!test) {
2334
+ throw new Error(`Expected a token with a 'for' property`);
2335
+ }
2336
+ })(token && typeof token === 'function' && 'for' in token) : {};
2337
+ }
2338
+ function _unsubscribe(token, cache) {
2339
+ asInternalToken(token);
2340
+ const identifier = token.for;
2332
2341
  if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
2333
2342
  if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
2334
2343
  if (!identifier) {
@@ -2338,9 +2347,20 @@ function _unsubscribe(tokens, token, cache) {
2338
2347
  }
2339
2348
  }
2340
2349
  if (identifier) {
2341
- tokens.delete(token);
2342
- const map = cache.get(identifier);
2343
- map?.delete(token);
2350
+ const callbacks = cache.get(identifier);
2351
+ if (!callbacks) {
2352
+ return;
2353
+ }
2354
+ const index = callbacks.indexOf(token);
2355
+ if (index === -1) {
2356
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2357
+ if (!test) {
2358
+ throw new Error(`Cannot unsubscribe a token that is not subscribed`);
2359
+ }
2360
+ })(index !== -1) : {};
2361
+ return;
2362
+ }
2363
+ callbacks.splice(index, 1);
2344
2364
  }
2345
2365
  }
2346
2366
 
@@ -2361,7 +2381,6 @@ class NotificationManager {
2361
2381
  this._buffered = new Map();
2362
2382
  this._hasFlush = false;
2363
2383
  this._cache = new Map();
2364
- this._tokens = new Map();
2365
2384
  }
2366
2385
 
2367
2386
  /**
@@ -2398,17 +2417,26 @@ class NotificationManager {
2398
2417
  throw new Error(`Expected to receive a stable Identifier to subscribe to`);
2399
2418
  }
2400
2419
  })(identifier === 'resource' || identifier === 'document' || isStableIdentifier(identifier) || isDocumentIdentifier(identifier)) : {};
2401
- let map = this._cache.get(identifier);
2402
- if (!map) {
2403
- map = new Map();
2404
- this._cache.set(identifier, map);
2420
+ let callbacks = this._cache.get(identifier);
2421
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2422
+ if (!test) {
2423
+ throw new Error(`expected to receive a valid callback`);
2424
+ }
2425
+ })(typeof callback === 'function') : {};
2426
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
2427
+ if (!test) {
2428
+ throw new Error(`cannot subscribe with the same callback twice`);
2429
+ }
2430
+ })(!callbacks || !callbacks.includes(callback)) : {};
2431
+ // we use the callback as the cancellation token
2432
+ //@ts-expect-error
2433
+ callback.for = identifier;
2434
+ if (!callbacks) {
2435
+ callbacks = [];
2436
+ this._cache.set(identifier, callbacks);
2405
2437
  }
2406
- const unsubToken = macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? {
2407
- _tokenRef: tokenId++
2408
- } : {};
2409
- map.set(unsubToken, callback);
2410
- this._tokens.set(unsubToken, identifier);
2411
- return unsubToken;
2438
+ callbacks.push(callback);
2439
+ return callback;
2412
2440
  }
2413
2441
 
2414
2442
  /**
@@ -2420,7 +2448,7 @@ class NotificationManager {
2420
2448
  */
2421
2449
  unsubscribe(token) {
2422
2450
  if (!this.isDestroyed) {
2423
- _unsubscribe(this._tokens, token, this._cache);
2451
+ _unsubscribe(token, this._cache);
2424
2452
  }
2425
2453
  }
2426
2454
 
@@ -2450,7 +2478,7 @@ class NotificationManager {
2450
2478
  }
2451
2479
  return false;
2452
2480
  }
2453
- const hasSubscribers = Boolean(this._cache.get(identifier)?.size);
2481
+ const hasSubscribers = Boolean(this._cache.get(identifier)?.length);
2454
2482
  if (isCacheOperationValue(value) || hasSubscribers) {
2455
2483
  let buffer = this._buffered.get(identifier);
2456
2484
  if (!buffer) {
@@ -2470,9 +2498,16 @@ class NotificationManager {
2470
2498
  }
2471
2499
  }
2472
2500
  }
2473
- } else if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
2474
- if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
2475
- count(`DISCARDED notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
2501
+ } else {
2502
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_NOTIFICATIONS)) {
2503
+ if (getGlobalConfig().WarpDrive.debug.LOG_NOTIFICATIONS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_NOTIFICATIONS) {
2504
+ log('notify', 'discarded', `${'type' in identifier ? identifier.type : 'document'}`, identifier.lid, `${value}`, key || '');
2505
+ }
2506
+ }
2507
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
2508
+ if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
2509
+ count(`DISCARDED notify ${'type' in identifier ? identifier.type : '<document>'} ${value} ${key}`);
2510
+ }
2476
2511
  }
2477
2512
  }
2478
2513
  return hasSubscribers;
@@ -2525,11 +2560,11 @@ class NotificationManager {
2525
2560
  });
2526
2561
  }
2527
2562
  }
2528
- const callbackMap = this._cache.get(identifier);
2529
- if (!callbackMap || !callbackMap.size) {
2563
+ const callbacks = this._cache.get(identifier);
2564
+ if (!callbacks || !callbacks.length) {
2530
2565
  return false;
2531
2566
  }
2532
- callbackMap.forEach(cb => {
2567
+ callbacks.forEach(cb => {
2533
2568
  // @ts-expect-error overload doesn't narrow within body
2534
2569
  cb(identifier, value, key);
2535
2570
  });
@@ -2537,7 +2572,6 @@ class NotificationManager {
2537
2572
  }
2538
2573
  destroy() {
2539
2574
  this.isDestroyed = true;
2540
- this._tokens.clear();
2541
2575
  this._cache.clear();
2542
2576
  }
2543
2577
  }
@@ -3124,6 +3158,15 @@ class IdentifierArray {
3124
3158
  })() : {};
3125
3159
  };
3126
3160
  }
3161
+ if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
3162
+ Object.defineProperty(this, '__SHOW_ME_THE_DATA_(debug mode only)__', {
3163
+ enumerable: false,
3164
+ configurable: true,
3165
+ get() {
3166
+ return proxy.slice();
3167
+ }
3168
+ });
3169
+ }
3127
3170
  createArrayTags(proxy, _SIGNAL);
3128
3171
  this[NOTIFY] = this[NOTIFY].bind(proxy);
3129
3172
  return proxy;
@@ -4327,16 +4370,108 @@ globalThis.setWarpDriveLogging = setLogging;
4327
4370
  globalThis.getWarpDriveRuntimeConfig = getRuntimeConfig;
4328
4371
  if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.LOG_METRIC_COUNTS)) {
4329
4372
  if (getGlobalConfig().WarpDrive.debug.LOG_METRIC_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.LOG_METRIC_COUNTS) {
4330
- // @ts-expect-error
4373
+ // @ts-expect-error adding to globalThis
4331
4374
  // eslint-disable-next-line
4332
4375
  globalThis.__WarpDriveMetricCountData = globalThis.__WarpDriveMetricCountData || {};
4333
4376
 
4334
- // @ts-expect-error
4377
+ // @ts-expect-error adding to globalThis
4335
4378
  globalThis.getWarpDriveMetricCounts = () => {
4336
4379
  // @ts-expect-error
4337
4380
  // eslint-disable-next-line
4338
- return globalThis.__WarpDriveMetricCountData;
4381
+ return structuredClone(globalThis.__WarpDriveMetricCountData);
4382
+ };
4383
+
4384
+ // @ts-expect-error adding to globalThis
4385
+ globalThis.resetWarpDriveMetricCounts = () => {
4386
+ // @ts-expect-error
4387
+ globalThis.__WarpDriveMetricCountData = {};
4339
4388
  };
4389
+ if (macroCondition(getGlobalConfig().WarpDrive.activeLogging.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS)) {
4390
+ if (getGlobalConfig().WarpDrive.debug.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS || globalThis.getWarpDriveRuntimeConfig().debug.__INTERNAL_LOG_NATIVE_MAP_SET_COUNTS) {
4391
+ // @ts-expect-error adding to globalThis
4392
+ globalThis.__primitiveInstanceId = 0;
4393
+ function interceptAndLog(klassName, methodName) {
4394
+ const klass = globalThis[klassName];
4395
+ if (methodName === 'constructor') {
4396
+ const instantiationLabel = `new ${klassName}()`;
4397
+ // @ts-expect-error
4398
+ globalThis[klassName] = class extends klass {
4399
+ // @ts-expect-error
4400
+ constructor(...args) {
4401
+ // eslint-disable-next-line
4402
+ super(...args);
4403
+ // @ts-expect-error
4404
+
4405
+ const instanceId = globalThis.__primitiveInstanceId++;
4406
+ // @ts-expect-error
4407
+ // eslint-disable-next-line
4408
+ globalThis.__WarpDriveMetricCountData[instantiationLabel] =
4409
+ // @ts-expect-error
4410
+ // eslint-disable-next-line
4411
+ (globalThis.__WarpDriveMetricCountData[instantiationLabel] || 0) + 1;
4412
+ // @ts-expect-error
4413
+ this.instanceName = `${klassName}:${instanceId} - ${new Error().stack?.split('\n')[2]}`;
4414
+ }
4415
+ };
4416
+ } else {
4417
+ // @ts-expect-error
4418
+ // eslint-disable-next-line
4419
+ const original = klass.prototype[methodName];
4420
+ const logName = `${klassName}.${methodName}`;
4421
+
4422
+ // @ts-expect-error
4423
+ klass.prototype[methodName] = function (...args) {
4424
+ // @ts-expect-error
4425
+ // eslint-disable-next-line
4426
+ globalThis.__WarpDriveMetricCountData[logName] = (globalThis.__WarpDriveMetricCountData[logName] || 0) + 1;
4427
+ // @ts-expect-error
4428
+ const {
4429
+ instanceName
4430
+ } = this;
4431
+ if (!instanceName) {
4432
+ // @ts-expect-error
4433
+ const instanceId = globalThis.__primitiveInstanceId++;
4434
+ // @ts-expect-error
4435
+ this.instanceName = `${klassName}.${methodName}:${instanceId} - ${new Error().stack?.split('\n')[2]}`;
4436
+ }
4437
+ const instanceLogName = `${logName} (${instanceName})`;
4438
+ // @ts-expect-error
4439
+ // eslint-disable-next-line
4440
+ globalThis.__WarpDriveMetricCountData[instanceLogName] =
4441
+ // @ts-expect-error
4442
+ // eslint-disable-next-line
4443
+ (globalThis.__WarpDriveMetricCountData[instanceLogName] || 0) + 1;
4444
+ // eslint-disable-next-line
4445
+ return original.apply(this, args);
4446
+ };
4447
+ }
4448
+ }
4449
+ interceptAndLog('Set', 'constructor');
4450
+ interceptAndLog('Set', 'add');
4451
+ interceptAndLog('Set', 'delete');
4452
+ interceptAndLog('Set', 'has');
4453
+ interceptAndLog('Set', 'set');
4454
+ interceptAndLog('Set', 'get');
4455
+ interceptAndLog('Map', 'constructor');
4456
+ interceptAndLog('Map', 'set');
4457
+ interceptAndLog('Map', 'delete');
4458
+ interceptAndLog('Map', 'has');
4459
+ interceptAndLog('Map', 'add');
4460
+ interceptAndLog('Map', 'get');
4461
+ interceptAndLog('WeakSet', 'constructor');
4462
+ interceptAndLog('WeakSet', 'add');
4463
+ interceptAndLog('WeakSet', 'delete');
4464
+ interceptAndLog('WeakSet', 'has');
4465
+ interceptAndLog('WeakSet', 'set');
4466
+ interceptAndLog('WeakSet', 'get');
4467
+ interceptAndLog('WeakMap', 'constructor');
4468
+ interceptAndLog('WeakMap', 'set');
4469
+ interceptAndLog('WeakMap', 'delete');
4470
+ interceptAndLog('WeakMap', 'has');
4471
+ interceptAndLog('WeakMap', 'add');
4472
+ interceptAndLog('WeakMap', 'get');
4473
+ }
4474
+ }
4340
4475
  }
4341
4476
  }
4342
4477