tutuca 0.9.73 → 0.9.76

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.
@@ -4247,6 +4247,9 @@ class Step {
4247
4247
  toAbstractPathStep() {
4248
4248
  return this;
4249
4249
  }
4250
+ pinKey(_v) {
4251
+ return this;
4252
+ }
4250
4253
  }
4251
4254
  function warnRawDynStep(op, step) {
4252
4255
  console.warn(`Path.${op} reached a DynStep: call toTransactionPath() first`, step);
@@ -4297,6 +4300,20 @@ class Path {
4297
4300
  }
4298
4301
  return new Path(out);
4299
4302
  }
4303
+ pinKeys(root) {
4304
+ let curVal = root;
4305
+ let out = null;
4306
+ for (let i = 0;i < this.steps.length; i++) {
4307
+ const step = this.steps[i];
4308
+ const pinned = step.pinKey(curVal);
4309
+ if (pinned !== step)
4310
+ (out ??= this.steps.slice())[i] = pinned;
4311
+ curVal = step.lookup(curVal, NONE);
4312
+ if (curVal === NONE)
4313
+ break;
4314
+ }
4315
+ return out ? new Path(out) : this;
4316
+ }
4300
4317
  lookup(v, dval = null) {
4301
4318
  let curVal = v;
4302
4319
  for (const step of this.steps) {
@@ -4582,6 +4599,10 @@ var init_path = __esm(() => {
4582
4599
  const key = root?.get(this.keyField, NONE);
4583
4600
  return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
4584
4601
  }
4602
+ pinKey(v) {
4603
+ const key = v?.get(this.keyField, NONE);
4604
+ return key === NONE ? this : new SeqStep(this.seqField, key);
4605
+ }
4585
4606
  };
4586
4607
  EachBindStep = class EachBindStep extends Step {
4587
4608
  constructor(seqVal, key) {
@@ -13744,12 +13765,14 @@ class Transactor {
13744
13765
  }
13745
13766
  async pushRequest(path, name, args = [], opts = {}, parent = null) {
13746
13767
  const curRoot = this.state.val;
13747
- const curLeaf = path.toTransactionPath().lookup(curRoot);
13768
+ const txnPath = path.toTransactionPath();
13769
+ const curLeaf = txnPath.lookup(curRoot);
13748
13770
  const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
13749
13771
  const resHandlerName = opts?.onResName ?? name;
13772
+ const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
13750
13773
  const push = (specificName, baseName, singleArg, result, error) => {
13751
13774
  const resArgs = specificName ? [singleArg] : [result, error];
13752
- const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent);
13775
+ const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
13753
13776
  this.pushTransaction(t);
13754
13777
  };
13755
13778
  try {
@@ -13824,8 +13847,11 @@ class Transaction {
13824
13847
  getHandlerAndArgs(_root, _instance, _comps) {
13825
13848
  return null;
13826
13849
  }
13850
+ getTransactionPath() {
13851
+ return this.path.toTransactionPath();
13852
+ }
13827
13853
  updateRootValue(curRoot, comps) {
13828
- const txnPath = this.path.toTransactionPath();
13854
+ const txnPath = this.getTransactionPath();
13829
13855
  const curLeaf = txnPath.lookup(curRoot);
13830
13856
  const newLeaf = this.callHandler(curRoot, curLeaf, comps);
13831
13857
  this._task?.complete?.({ value: newLeaf, old: curLeaf });
@@ -13990,6 +14016,13 @@ var init_transactor = __esm(() => {
13990
14016
  };
13991
14017
  ResponseEvent = class ResponseEvent extends NameArgsTransaction {
13992
14018
  handlerProp = "response";
14019
+ constructor(path, transactor, name, args, parent, txnPath = null) {
14020
+ super(path, transactor, name, args, parent);
14021
+ this._txnPath = txnPath;
14022
+ }
14023
+ getTransactionPath() {
14024
+ return this._txnPath ?? super.getTransactionPath();
14025
+ }
13993
14026
  };
13994
14027
  SendEvent = class SendEvent extends NameArgsTransaction {
13995
14028
  handlerProp = "receive";
@@ -1,5 +1,5 @@
1
1
  // dev.js
2
- import { expect } from "chai";
2
+ import { expect, use } from "chai";
3
3
 
4
4
  // src/value.js
5
5
  import { is } from "immutable";
@@ -20,6 +20,9 @@ class Step {
20
20
  toAbstractPathStep() {
21
21
  return this;
22
22
  }
23
+ pinKey(_v) {
24
+ return this;
25
+ }
23
26
  }
24
27
 
25
28
  class BindStep extends Step {
@@ -101,6 +104,10 @@ class SeqAccessStep extends Step {
101
104
  const key = root?.get(this.keyField, NONE);
102
105
  return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
103
106
  }
107
+ pinKey(v) {
108
+ const key = v?.get(this.keyField, NONE);
109
+ return key === NONE ? this : new SeqStep(this.seqField, key);
110
+ }
104
111
  }
105
112
 
106
113
  class EachBindStep extends Step {
@@ -223,6 +230,20 @@ class Path {
223
230
  }
224
231
  return new Path(out);
225
232
  }
233
+ pinKeys(root) {
234
+ let curVal = root;
235
+ let out = null;
236
+ for (let i = 0;i < this.steps.length; i++) {
237
+ const step = this.steps[i];
238
+ const pinned = step.pinKey(curVal);
239
+ if (pinned !== step)
240
+ (out ??= this.steps.slice())[i] = pinned;
241
+ curVal = step.lookup(curVal, NONE);
242
+ if (curVal === NONE)
243
+ break;
244
+ }
245
+ return out ? new Path(out) : this;
246
+ }
226
247
  lookup(v, dval = null) {
227
248
  let curVal = v;
228
249
  for (const step of this.steps) {
@@ -2301,6 +2322,87 @@ function compileModifiers(eventName, names) {
2301
2322
  };
2302
2323
  }
2303
2324
 
2325
+ // src/chai-jest.js
2326
+ function jestMatchers(chai, utils) {
2327
+ const A = chai.Assertion;
2328
+ const m = (name, fn) => A.addMethod(name, fn);
2329
+ m("toBe", function(expected) {
2330
+ this.assert(Object.is(this._obj, expected), "expected #{this} to be #{exp}", "expected #{this} not to be #{exp}", expected, this._obj);
2331
+ });
2332
+ m("toEqual", function(expected) {
2333
+ this.assert(utils.eql(this._obj, expected), "expected #{this} to deeply equal #{exp}", "expected #{this} not to deeply equal #{exp}", expected, this._obj, true);
2334
+ });
2335
+ m("toBeTruthy", function() {
2336
+ this.assert(Boolean(this._obj), "expected #{this} to be truthy", "expected #{this} not to be truthy");
2337
+ });
2338
+ m("toBeFalsy", function() {
2339
+ this.assert(!this._obj, "expected #{this} to be falsy", "expected #{this} not to be falsy");
2340
+ });
2341
+ m("toBeNull", function() {
2342
+ this.assert(this._obj === null, "expected #{this} to be null", "expected #{this} not to be null");
2343
+ });
2344
+ m("toBeUndefined", function() {
2345
+ this.assert(this._obj === undefined, "expected #{this} to be undefined", "expected #{this} not to be undefined");
2346
+ });
2347
+ m("toBeDefined", function() {
2348
+ this.assert(this._obj !== undefined, "expected #{this} to be defined", "expected #{this} to be undefined");
2349
+ });
2350
+ m("toBeNaN", function() {
2351
+ this.assert(Number.isNaN(this._obj), "expected #{this} to be NaN", "expected #{this} not to be NaN");
2352
+ });
2353
+ const compare = (name, op, word) => m(name, function(expected) {
2354
+ this.assert(op(this._obj, expected), `expected #{this} to be ${word} #{exp}`, `expected #{this} not to be ${word} #{exp}`, expected);
2355
+ });
2356
+ compare("toBeGreaterThan", (a, b) => a > b, "greater than");
2357
+ compare("toBeGreaterThanOrEqual", (a, b) => a >= b, "greater than or equal to");
2358
+ compare("toBeLessThan", (a, b) => a < b, "less than");
2359
+ compare("toBeLessThanOrEqual", (a, b) => a <= b, "less than or equal to");
2360
+ m("toBeCloseTo", function(expected, numDigits = 2) {
2361
+ const pass = Math.abs(expected - this._obj) < 10 ** -numDigits / 2;
2362
+ this.assert(pass, `expected #{this} to be close to #{exp} (${numDigits} digits)`, `expected #{this} not to be close to #{exp} (${numDigits} digits)`, expected);
2363
+ });
2364
+ m("toContain", function(item) {
2365
+ const obj = this._obj;
2366
+ const ok = typeof obj === "string" ? obj.includes(item) : Array.from(obj).includes(item);
2367
+ this.assert(ok, "expected #{this} to contain #{exp}", "expected #{this} not to contain #{exp}", item);
2368
+ });
2369
+ m("toHaveLength", function(length) {
2370
+ const actual = this._obj == null ? undefined : this._obj.length;
2371
+ this.assert(actual === length, "expected #{this} to have length #{exp}", "expected #{this} not to have length #{exp}", length, actual);
2372
+ });
2373
+ m("toMatch", function(expected) {
2374
+ const obj = this._obj;
2375
+ const ok = expected instanceof RegExp ? expected.test(obj) : String(obj).includes(expected);
2376
+ this.assert(ok, "expected #{this} to match #{exp}", "expected #{this} not to match #{exp}", expected);
2377
+ });
2378
+ m("toHaveProperty", function(path, ...rest) {
2379
+ const keys = Array.isArray(path) ? path : String(path).split(".");
2380
+ let cur = this._obj;
2381
+ let found = true;
2382
+ for (const k of keys) {
2383
+ if (cur != null && k in Object(cur))
2384
+ cur = cur[k];
2385
+ else {
2386
+ found = false;
2387
+ break;
2388
+ }
2389
+ }
2390
+ const pass = found && (rest.length === 0 || utils.eql(cur, rest[0]));
2391
+ this.assert(pass, "expected #{this} to have property #{exp}", "expected #{this} not to have property #{exp}", path);
2392
+ });
2393
+ m("toBeInstanceOf", function(ctor) {
2394
+ this.assert(this._obj instanceof ctor, "expected #{this} to be an instance of #{exp}", "expected #{this} not to be an instance of #{exp}", ctor.name ?? ctor);
2395
+ });
2396
+ m("toThrow", function(expected) {
2397
+ const a = new chai.Assertion(this._obj);
2398
+ if (utils.flag(this, "negate")) {
2399
+ expected === undefined ? a.to.not.throw() : a.to.not.throw(expected);
2400
+ } else {
2401
+ expected === undefined ? a.to.throw() : a.to.throw(expected);
2402
+ }
2403
+ });
2404
+ }
2405
+
2304
2406
  // src/util/parsectx.js
2305
2407
  class ParseCtxClassSetCollector extends ParseContext {
2306
2408
  constructor(...args) {
@@ -6329,12 +6431,14 @@ class Transactor {
6329
6431
  }
6330
6432
  async pushRequest(path, name, args = [], opts = {}, parent = null) {
6331
6433
  const curRoot = this.state.val;
6332
- const curLeaf = path.toTransactionPath().lookup(curRoot);
6434
+ const txnPath = path.toTransactionPath();
6435
+ const curLeaf = txnPath.lookup(curRoot);
6333
6436
  const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
6334
6437
  const resHandlerName = opts?.onResName ?? name;
6438
+ const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
6335
6439
  const push = (specificName, baseName, singleArg, result, error) => {
6336
6440
  const resArgs = specificName ? [singleArg] : [result, error];
6337
- const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent);
6441
+ const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
6338
6442
  this.pushTransaction(t);
6339
6443
  };
6340
6444
  try {
@@ -6409,8 +6513,11 @@ class Transaction {
6409
6513
  getHandlerAndArgs(_root, _instance, _comps) {
6410
6514
  return null;
6411
6515
  }
6516
+ getTransactionPath() {
6517
+ return this.path.toTransactionPath();
6518
+ }
6412
6519
  updateRootValue(curRoot, comps) {
6413
- const txnPath = this.path.toTransactionPath();
6520
+ const txnPath = this.getTransactionPath();
6414
6521
  const curLeaf = txnPath.lookup(curRoot);
6415
6522
  const newLeaf = this.callHandler(curRoot, curLeaf, comps);
6416
6523
  this._task?.complete?.({ value: newLeaf, old: curLeaf });
@@ -6519,6 +6626,13 @@ class NameArgsTransaction extends Transaction {
6519
6626
 
6520
6627
  class ResponseEvent extends NameArgsTransaction {
6521
6628
  handlerProp = "response";
6629
+ constructor(path, transactor, name, args, parent, txnPath = null) {
6630
+ super(path, transactor, name, args, parent);
6631
+ this._txnPath = txnPath;
6632
+ }
6633
+ getTransactionPath() {
6634
+ return this._txnPath ?? super.getTransactionPath();
6635
+ }
6522
6636
  }
6523
6637
 
6524
6638
  class SendEvent extends NameArgsTransaction {
@@ -7905,6 +8019,7 @@ function collectIterBindings(Comp, compInstance, seq, opts = {}) {
7905
8019
  }
7906
8020
 
7907
8021
  // dev.js
8022
+ use(jestMatchers);
7908
8023
  async function test2(opts = {}) {
7909
8024
  const report = await runTests({ expect, ...opts });
7910
8025
  reportTestReportToConsole(report);
@@ -7685,6 +7685,9 @@ class Step {
7685
7685
  toAbstractPathStep() {
7686
7686
  return this;
7687
7687
  }
7688
+ pinKey(_v) {
7689
+ return this;
7690
+ }
7688
7691
  }
7689
7692
 
7690
7693
  class BindStep extends Step {
@@ -7766,6 +7769,10 @@ class SeqAccessStep extends Step {
7766
7769
  const key = root?.get(this.keyField, NONE);
7767
7770
  return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
7768
7771
  }
7772
+ pinKey(v) {
7773
+ const key = v?.get(this.keyField, NONE);
7774
+ return key === NONE ? this : new SeqStep(this.seqField, key);
7775
+ }
7769
7776
  }
7770
7777
 
7771
7778
  class EachBindStep extends Step {
@@ -7888,6 +7895,20 @@ class Path {
7888
7895
  }
7889
7896
  return new Path(out);
7890
7897
  }
7898
+ pinKeys(root) {
7899
+ let curVal = root;
7900
+ let out = null;
7901
+ for (let i = 0;i < this.steps.length; i++) {
7902
+ const step = this.steps[i];
7903
+ const pinned = step.pinKey(curVal);
7904
+ if (pinned !== step)
7905
+ (out ??= this.steps.slice())[i] = pinned;
7906
+ curVal = step.lookup(curVal, NONE);
7907
+ if (curVal === NONE)
7908
+ break;
7909
+ }
7910
+ return out ? new Path(out) : this;
7911
+ }
7891
7912
  lookup(v, dval = null) {
7892
7913
  let curVal = v;
7893
7914
  for (const step of this.steps) {
@@ -9966,6 +9987,87 @@ function compileModifiers(eventName, names) {
9966
9987
  };
9967
9988
  }
9968
9989
 
9990
+ // src/chai-jest.js
9991
+ function jestMatchers(chai, utils) {
9992
+ const A = chai.Assertion;
9993
+ const m = (name, fn) => A.addMethod(name, fn);
9994
+ m("toBe", function(expected) {
9995
+ this.assert(Object.is(this._obj, expected), "expected #{this} to be #{exp}", "expected #{this} not to be #{exp}", expected, this._obj);
9996
+ });
9997
+ m("toEqual", function(expected) {
9998
+ this.assert(utils.eql(this._obj, expected), "expected #{this} to deeply equal #{exp}", "expected #{this} not to deeply equal #{exp}", expected, this._obj, true);
9999
+ });
10000
+ m("toBeTruthy", function() {
10001
+ this.assert(Boolean(this._obj), "expected #{this} to be truthy", "expected #{this} not to be truthy");
10002
+ });
10003
+ m("toBeFalsy", function() {
10004
+ this.assert(!this._obj, "expected #{this} to be falsy", "expected #{this} not to be falsy");
10005
+ });
10006
+ m("toBeNull", function() {
10007
+ this.assert(this._obj === null, "expected #{this} to be null", "expected #{this} not to be null");
10008
+ });
10009
+ m("toBeUndefined", function() {
10010
+ this.assert(this._obj === undefined, "expected #{this} to be undefined", "expected #{this} not to be undefined");
10011
+ });
10012
+ m("toBeDefined", function() {
10013
+ this.assert(this._obj !== undefined, "expected #{this} to be defined", "expected #{this} to be undefined");
10014
+ });
10015
+ m("toBeNaN", function() {
10016
+ this.assert(Number.isNaN(this._obj), "expected #{this} to be NaN", "expected #{this} not to be NaN");
10017
+ });
10018
+ const compare = (name, op, word) => m(name, function(expected) {
10019
+ this.assert(op(this._obj, expected), `expected #{this} to be ${word} #{exp}`, `expected #{this} not to be ${word} #{exp}`, expected);
10020
+ });
10021
+ compare("toBeGreaterThan", (a, b) => a > b, "greater than");
10022
+ compare("toBeGreaterThanOrEqual", (a, b) => a >= b, "greater than or equal to");
10023
+ compare("toBeLessThan", (a, b) => a < b, "less than");
10024
+ compare("toBeLessThanOrEqual", (a, b) => a <= b, "less than or equal to");
10025
+ m("toBeCloseTo", function(expected, numDigits = 2) {
10026
+ const pass = Math.abs(expected - this._obj) < 10 ** -numDigits / 2;
10027
+ this.assert(pass, `expected #{this} to be close to #{exp} (${numDigits} digits)`, `expected #{this} not to be close to #{exp} (${numDigits} digits)`, expected);
10028
+ });
10029
+ m("toContain", function(item) {
10030
+ const obj = this._obj;
10031
+ const ok = typeof obj === "string" ? obj.includes(item) : Array.from(obj).includes(item);
10032
+ this.assert(ok, "expected #{this} to contain #{exp}", "expected #{this} not to contain #{exp}", item);
10033
+ });
10034
+ m("toHaveLength", function(length) {
10035
+ const actual = this._obj == null ? undefined : this._obj.length;
10036
+ this.assert(actual === length, "expected #{this} to have length #{exp}", "expected #{this} not to have length #{exp}", length, actual);
10037
+ });
10038
+ m("toMatch", function(expected) {
10039
+ const obj = this._obj;
10040
+ const ok = expected instanceof RegExp ? expected.test(obj) : String(obj).includes(expected);
10041
+ this.assert(ok, "expected #{this} to match #{exp}", "expected #{this} not to match #{exp}", expected);
10042
+ });
10043
+ m("toHaveProperty", function(path, ...rest) {
10044
+ const keys = Array.isArray(path) ? path : String(path).split(".");
10045
+ let cur = this._obj;
10046
+ let found = true;
10047
+ for (const k of keys) {
10048
+ if (cur != null && k in Object(cur))
10049
+ cur = cur[k];
10050
+ else {
10051
+ found = false;
10052
+ break;
10053
+ }
10054
+ }
10055
+ const pass = found && (rest.length === 0 || utils.eql(cur, rest[0]));
10056
+ this.assert(pass, "expected #{this} to have property #{exp}", "expected #{this} not to have property #{exp}", path);
10057
+ });
10058
+ m("toBeInstanceOf", function(ctor) {
10059
+ this.assert(this._obj instanceof ctor, "expected #{this} to be an instance of #{exp}", "expected #{this} not to be an instance of #{exp}", ctor.name ?? ctor);
10060
+ });
10061
+ m("toThrow", function(expected) {
10062
+ const a = new chai.Assertion(this._obj);
10063
+ if (utils.flag(this, "negate")) {
10064
+ expected === undefined ? a.to.not.throw() : a.to.not.throw(expected);
10065
+ } else {
10066
+ expected === undefined ? a.to.throw() : a.to.throw(expected);
10067
+ }
10068
+ });
10069
+ }
10070
+
9969
10071
  // src/util/parsectx.js
9970
10072
  class ParseCtxClassSetCollector extends ParseContext {
9971
10073
  constructor(...args) {
@@ -13994,12 +14096,14 @@ class Transactor {
13994
14096
  }
13995
14097
  async pushRequest(path, name, args = [], opts = {}, parent = null) {
13996
14098
  const curRoot = this.state.val;
13997
- const curLeaf = path.toTransactionPath().lookup(curRoot);
14099
+ const txnPath = path.toTransactionPath();
14100
+ const curLeaf = txnPath.lookup(curRoot);
13998
14101
  const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
13999
14102
  const resHandlerName = opts?.onResName ?? name;
14103
+ const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
14000
14104
  const push = (specificName, baseName, singleArg, result, error) => {
14001
14105
  const resArgs = specificName ? [singleArg] : [result, error];
14002
- const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent);
14106
+ const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
14003
14107
  this.pushTransaction(t);
14004
14108
  };
14005
14109
  try {
@@ -14074,8 +14178,11 @@ class Transaction {
14074
14178
  getHandlerAndArgs(_root, _instance, _comps) {
14075
14179
  return null;
14076
14180
  }
14181
+ getTransactionPath() {
14182
+ return this.path.toTransactionPath();
14183
+ }
14077
14184
  updateRootValue(curRoot, comps) {
14078
- const txnPath = this.path.toTransactionPath();
14185
+ const txnPath = this.getTransactionPath();
14079
14186
  const curLeaf = txnPath.lookup(curRoot);
14080
14187
  const newLeaf = this.callHandler(curRoot, curLeaf, comps);
14081
14188
  this._task?.complete?.({ value: newLeaf, old: curLeaf });
@@ -14184,6 +14291,13 @@ class NameArgsTransaction extends Transaction {
14184
14291
 
14185
14292
  class ResponseEvent extends NameArgsTransaction {
14186
14293
  handlerProp = "response";
14294
+ constructor(path, transactor, name, args, parent, txnPath = null) {
14295
+ super(path, transactor, name, args, parent);
14296
+ this._txnPath = txnPath;
14297
+ }
14298
+ getTransactionPath() {
14299
+ return this._txnPath ?? super.getTransactionPath();
14300
+ }
14187
14301
  }
14188
14302
 
14189
14303
  class SendEvent extends NameArgsTransaction {
@@ -15510,6 +15624,7 @@ function collectIterBindings(Comp, compInstance, seq, opts = {}) {
15510
15624
  }
15511
15625
 
15512
15626
  // dev.js
15627
+ use(jestMatchers);
15513
15628
  async function test3(opts = {}) {
15514
15629
  const report = await runTests({ expect, ...opts });
15515
15630
  reportTestReportToConsole(report);