@dra2020/baseclient 1.0.173 → 1.0.175
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/baseclient.js +94 -12
- package/dist/baseclient.js.map +1 -1
- package/dist/fsm/fsm.d.ts +5 -0
- package/dist/geo/multiblockmapping.d.ts +6 -2
- package/lib/fsm/fsm.ts +47 -1
- package/lib/geo/multiblockmapping.ts +62 -8
- package/package.json +1 -1
package/dist/baseclient.js
CHANGED
|
@@ -2261,6 +2261,8 @@ class FsmManager {
|
|
|
2261
2261
|
this.bTickSet = false;
|
|
2262
2262
|
this.theTickList = new Set();
|
|
2263
2263
|
this.theBusyLoopCount = 0;
|
|
2264
|
+
this.theExceptionCount = 0;
|
|
2265
|
+
this.onException = (fsm, err) => { console.error(`Fsm(${fsm.constructor.name}): exception in tick:`, err); };
|
|
2264
2266
|
this.doTick = this.doTick.bind(this);
|
|
2265
2267
|
}
|
|
2266
2268
|
forceTick(fsm) {
|
|
@@ -2277,7 +2279,14 @@ class FsmManager {
|
|
|
2277
2279
|
nLoops++;
|
|
2278
2280
|
let thisTickList = this.theTickList;
|
|
2279
2281
|
this.theTickList = new Set();
|
|
2280
|
-
thisTickList.forEach((f) =>
|
|
2282
|
+
thisTickList.forEach((f) => {
|
|
2283
|
+
try {
|
|
2284
|
+
f.tick();
|
|
2285
|
+
}
|
|
2286
|
+
catch (err) {
|
|
2287
|
+
this.tickException(f, err);
|
|
2288
|
+
}
|
|
2289
|
+
});
|
|
2281
2290
|
}
|
|
2282
2291
|
if (this.theTickList.size == 0)
|
|
2283
2292
|
this.theBusyLoopCount = 0;
|
|
@@ -2285,6 +2294,27 @@ class FsmManager {
|
|
|
2285
2294
|
this.theBusyLoopCount++;
|
|
2286
2295
|
this.theEpoch++;
|
|
2287
2296
|
}
|
|
2297
|
+
// An exception escaping a tick would otherwise unwind out of setImmediate and take down the whole
|
|
2298
|
+
// process (or, in the browser, leave the tick loop wedged). Instead, report it and let the Fsm
|
|
2299
|
+
// fail itself so anything waiting on it sees a dependent error rather than hanging forever.
|
|
2300
|
+
tickException(f, err) {
|
|
2301
|
+
this.theExceptionCount++;
|
|
2302
|
+
try {
|
|
2303
|
+
this.onException(f, err);
|
|
2304
|
+
}
|
|
2305
|
+
catch (e) { }
|
|
2306
|
+
try {
|
|
2307
|
+
f.tickException(err);
|
|
2308
|
+
}
|
|
2309
|
+
catch (e) {
|
|
2310
|
+
try {
|
|
2311
|
+
this.onException(f, e);
|
|
2312
|
+
}
|
|
2313
|
+
catch (e2) { }
|
|
2314
|
+
if (!f.done)
|
|
2315
|
+
f.setState(exports.FSM_ERROR);
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2288
2318
|
}
|
|
2289
2319
|
exports.FsmManager = FsmManager;
|
|
2290
2320
|
class Fsm {
|
|
@@ -2364,6 +2394,12 @@ class Fsm {
|
|
|
2364
2394
|
}
|
|
2365
2395
|
tick() {
|
|
2366
2396
|
}
|
|
2397
|
+
// Called (after FsmManager.onException has reported it) when tick() throws. Override to clean up or
|
|
2398
|
+
// respond, but make sure the Fsm ends up done.
|
|
2399
|
+
tickException(err) {
|
|
2400
|
+
if (!this.done)
|
|
2401
|
+
this.setState(exports.FSM_ERROR);
|
|
2402
|
+
}
|
|
2367
2403
|
}
|
|
2368
2404
|
exports.Fsm = Fsm;
|
|
2369
2405
|
// Launches callback provided when the associated Fsm (or Fsm array) completes.
|
|
@@ -3451,6 +3487,16 @@ function reverseBlockMapping(bm) {
|
|
|
3451
3487
|
Object.values(rev).forEach((a) => a.sort());
|
|
3452
3488
|
return rev;
|
|
3453
3489
|
}
|
|
3490
|
+
// A set of block mappings consulted as one, without copying any of them.
|
|
3491
|
+
//
|
|
3492
|
+
// Entries are either independent (e.g. one per state of a multi-state map, whose block ids never
|
|
3493
|
+
// overlap) or overlapping (a base mapping followed by overrides such as precinct updates). Overlapping
|
|
3494
|
+
// entries must be added in priority order: map() and rev() walk from the last entry back, so a later
|
|
3495
|
+
// entry wins.
|
|
3496
|
+
//
|
|
3497
|
+
// A full block mapping, and the reverse mapping computed from it, are large (TX has ~670K blocks), so
|
|
3498
|
+
// combining mappings shares them rather than copying: add() takes an already-computed reverse mapping,
|
|
3499
|
+
// and addFrom() takes both from another MultiBlockMapping.
|
|
3454
3500
|
class MultiBlockMapping {
|
|
3455
3501
|
constructor(tag, bm) {
|
|
3456
3502
|
this.entries = [];
|
|
@@ -3458,16 +3504,30 @@ class MultiBlockMapping {
|
|
|
3458
3504
|
if (tag && bm)
|
|
3459
3505
|
this.entries.push({ tag, bm });
|
|
3460
3506
|
}
|
|
3461
|
-
|
|
3462
|
-
|
|
3507
|
+
// Adds or replaces the entry for tag. Pass rbm when the reverse mapping of bm is already computed,
|
|
3508
|
+
// so it is shared rather than built again.
|
|
3509
|
+
add(tag, bm, rbm) {
|
|
3510
|
+
let e = this.entries.find(e => e.tag === tag);
|
|
3511
|
+
if (e) {
|
|
3463
3512
|
e.bm = bm;
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3513
|
+
if (rbm)
|
|
3514
|
+
e.rbm = rbm;
|
|
3515
|
+
else
|
|
3516
|
+
delete e.rbm;
|
|
3517
|
+
}
|
|
3518
|
+
else
|
|
3519
|
+
this.entries.push(rbm ? { tag, bm, rbm } : { tag, bm });
|
|
3469
3520
|
this.stamp++;
|
|
3470
3521
|
}
|
|
3522
|
+
// Adds the entry for tag from another mapping - or, with no tag, all of its entries in order - sharing
|
|
3523
|
+
// both the block mapping and its reverse mapping. The reverse mapping is computed on the source first
|
|
3524
|
+
// if need be, so that it is built once, there, and not separately in each mapping that shares it.
|
|
3525
|
+
addFrom(src, tag) {
|
|
3526
|
+
src.entries.forEach(e => {
|
|
3527
|
+
if (tag === undefined || e.tag === tag)
|
|
3528
|
+
this.add(e.tag, e.bm, src.rbmOf(e.tag));
|
|
3529
|
+
});
|
|
3530
|
+
}
|
|
3471
3531
|
remove(tag) {
|
|
3472
3532
|
for (let i = this.entries.length - 1; i >= 0; i--)
|
|
3473
3533
|
if (this.entries[i].tag === tag) {
|
|
@@ -3475,6 +3535,9 @@ class MultiBlockMapping {
|
|
|
3475
3535
|
this.entries.splice(i, 1);
|
|
3476
3536
|
}
|
|
3477
3537
|
}
|
|
3538
|
+
has(tag) {
|
|
3539
|
+
return this.entries.some(e => e.tag === tag);
|
|
3540
|
+
}
|
|
3478
3541
|
map(blockid) {
|
|
3479
3542
|
// Walk backwards to pick up overrides first
|
|
3480
3543
|
for (let i = this.entries.length - 1; i >= 0; i--) {
|
|
@@ -3494,6 +3557,17 @@ class MultiBlockMapping {
|
|
|
3494
3557
|
let e = this.entries.find(e => e.tag === tag);
|
|
3495
3558
|
return e ? e.bm : null;
|
|
3496
3559
|
}
|
|
3560
|
+
// The reverse mapping of the entry for tag, computed on first use.
|
|
3561
|
+
rbmOf(tag) {
|
|
3562
|
+
let e = this.entries.find(e => e.tag === tag);
|
|
3563
|
+
if (!e)
|
|
3564
|
+
return null;
|
|
3565
|
+
if (!e.rbm)
|
|
3566
|
+
e.rbm = reverseBlockMapping(e.bm);
|
|
3567
|
+
return e.rbm;
|
|
3568
|
+
}
|
|
3569
|
+
// Maps through the first entry only. Meaningful only where that entry is the base mapping and the
|
|
3570
|
+
// rest are overrides; for independent entries (a multi-state mapping) use map().
|
|
3497
3571
|
mapmain(blockid) {
|
|
3498
3572
|
return this.entries.length ? this.entries[0].bm[blockid] : undefined;
|
|
3499
3573
|
}
|
|
@@ -3507,10 +3581,18 @@ class MultiBlockMapping {
|
|
|
3507
3581
|
}
|
|
3508
3582
|
return undefined;
|
|
3509
3583
|
}
|
|
3510
|
-
//
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3584
|
+
// Walks the blocks of one entry: the one for tag, or with no tag the first. This is the right walk
|
|
3585
|
+
// over "all blocks" only when that entry is a base mapping covering them and the others are overrides
|
|
3586
|
+
// of it - it sees nothing of a multi-state mapping but its first state. See forEachBlock.
|
|
3587
|
+
forEachBase(cb, tag) {
|
|
3588
|
+
let e = tag === undefined ? this.entries[0] : this.entries.find(e => e.tag === tag);
|
|
3589
|
+
if (e)
|
|
3590
|
+
Object.keys(e.bm).forEach(blockid => cb(blockid));
|
|
3591
|
+
}
|
|
3592
|
+
// Walks the blocks of every entry. A block mapped by several entries (a base and its overrides) is
|
|
3593
|
+
// visited once for each of them; independent entries (a multi-state mapping) never repeat a block.
|
|
3594
|
+
forEachBlock(cb) {
|
|
3595
|
+
this.entries.forEach(e => Object.keys(e.bm).forEach(blockid => cb(blockid)));
|
|
3514
3596
|
}
|
|
3515
3597
|
// Walk maps in reverse order, careful to not invoke on same geoid
|
|
3516
3598
|
forEachRev(cb) {
|