teamplay 0.4.0-alpha.92 → 0.4.0-alpha.94

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.
@@ -407,7 +407,7 @@ Compatibility mode intentionally aligns mutators with Racer. This differs from c
407
407
  | `set` | Uses deep-diff path (`dataTree.set` + internal `setDiffDeep`). | Path-targeted replace semantics, Racer-like. `undefined` keeps delete semantics. |
408
408
  | `setEach` | Not a special API in core mutators. | Per-key compat `set` (not `assign` merge/delete behavior). |
409
409
  | `setDiffDeep` | Deep-diff engine (`utils/setDiffDeep.js`). | Recursive Racer-like diff implemented via compat mutators (`set` / `del`) on nested paths. |
410
- | `setDiff` | N/A as compat shim. | Alias to compat `set` for both signatures: `setDiff(value)` and `setDiff(path, value)`. |
410
+ | `setDiff` | N/A as compat shim. | Racer-like full replace with exact-equality no-op (`===` / `NaN`). Equivalent objects / arrays still replace. |
411
411
 
412
412
  Migration note: compat behavior is intentionally Racer-aligned and may differ from core mutators.
413
413
  Composite compat mutators (`setEach`, `setDiffDeep`) apply updates atomically for Teamplay-scheduled observers via the runtime batch scheduler.
@@ -474,13 +474,17 @@ await $.users.user1.setDiffDeep({ profile: { name: 'Kate' } }) // deep-diff path
474
474
 
475
475
  ### setDiff(path?, value)
476
476
 
477
- Alias for compat `set` in both forms:
478
- - `setDiff(value)` -> same as `set(value)`
479
- - `setDiff(path, value)` -> same as `set(path, value)`
477
+ Racer-like full replace at the target path.
478
+ - No-op only when previous and next values are exactly equal (`===`) or both `NaN`
479
+ - Equivalent objects / arrays still perform a replace
480
+ - Unlike `setDiffDeep`, this is not a recursive diff
480
481
 
481
482
  ```js
483
+ await $.users.user1.set('count', 1)
484
+ await $.users.user1.setDiff('count', 1) // no-op
485
+
482
486
  await $.users.user1.setDiff({ profile: { name: 'Kate' } })
483
- await $.users.user1.setDiff('profile', { name: 'Bob' })
487
+ await $.users.user1.setDiff('profile', { name: 'Bob' }) // full replace
484
488
  ```
485
489
 
486
490
  ### setEach(path?, object)
@@ -289,10 +289,16 @@ class SignalCompat extends Signal {
289
289
  const forwarded = forwardRef(this, 'setDiff', arguments)
290
290
  if (forwarded) return forwarded
291
291
  if (arguments.length > 2) throw Error('Signal.setDiff() expects one or two arguments')
292
- if (arguments.length === 1) {
293
- return this.set(path)
292
+ let segments = []
293
+ if (arguments.length === 2) {
294
+ segments = parseAtSubpath(path, 1, 'Signal.setDiff()')
295
+ } else if (arguments.length === 1) {
296
+ value = path
294
297
  }
295
- return this.set(path, value)
298
+ const $target = resolveRelativePathTarget(this, segments)
299
+ const before = $target.peek()
300
+ if (racerEqualCompat(before, value)) return
301
+ return setReplaceOnSignal($target, value)
296
302
  }
297
303
 
298
304
  async setEach (path, object) {
@@ -1090,6 +1096,10 @@ function deepEqualCompat (left, right) {
1090
1096
  return true
1091
1097
  }
1092
1098
 
1099
+ function racerEqualCompat (left, right) {
1100
+ return left === right || (Number.isNaN(left) && Number.isNaN(right))
1101
+ }
1102
+
1093
1103
  function getSignalValueAt ($signal, segments) {
1094
1104
  const $target = resolveRelativePathTarget($signal, segments)
1095
1105
  return $target.get()
package/orm/Query.js CHANGED
@@ -9,7 +9,7 @@ import FinalizationRegistry from '../utils/MockFinalizationRegistry.js'
9
9
  import SubscriptionState from './SubscriptionState.js'
10
10
  import { getIdFieldsForSegments, injectIdFields, isPlainObject } from './idFields.js'
11
11
  import { getSubscriptionGcDelay } from './subscriptionGcDelay.js'
12
- import { getScopedSignalHash } from './rootScope.js'
12
+ import { getScopedSignalHash, normalizeRootId } from './rootScope.js'
13
13
  import { getRoot, ROOT_ID, getRootTransportMode } from './Root.js'
14
14
  import { registerRootOwnedRuntime, unregisterRootOwnedRuntime } from './rootContext.js'
15
15
  import {
@@ -980,7 +980,7 @@ function detachQueryRoot (query, rootId) {
980
980
  }
981
981
 
982
982
  function getOwningRootId ($query) {
983
- return getRoot($query)?.[ROOT_ID]
983
+ return normalizeRootId(getRoot($query)?.[ROOT_ID])
984
984
  }
985
985
 
986
986
  function getQueryOwnerKey (rootId, transportHash) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teamplay",
3
- "version": "0.4.0-alpha.92",
3
+ "version": "0.4.0-alpha.94",
4
4
  "description": "Full-stack signals ORM with multiplayer",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -83,5 +83,5 @@
83
83
  ]
84
84
  },
85
85
  "license": "MIT",
86
- "gitHead": "d55bd0417f7611c11584ae6400e5e111cc0ec9e3"
86
+ "gitHead": "28a9de4a846b5f36c31033c1c3486074cf9b86fc"
87
87
  }