@cubingcenter/scrambler 0.6.3 → 0.8.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/README.md +17 -4
- package/dist/core/api.d.ts.map +1 -1
- package/dist/core/api.js +10 -2
- package/dist/puzzles/cube2/solver/browser-loader.d.ts +4 -7
- package/dist/puzzles/cube2/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/browser-loader.js +42 -14
- package/dist/puzzles/cube2/solver/generated-assets.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/generated-assets.js +8 -3
- package/dist/puzzles/cube2/solver/search.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/search.js +3 -3
- package/dist/puzzles/cube2/solver/tables.d.ts +6 -0
- package/dist/puzzles/cube2/solver/tables.d.ts.map +1 -1
- package/dist/puzzles/cube2/solver/tables.js +16 -2
- package/dist/puzzles/cube3/index.d.ts +1 -0
- package/dist/puzzles/cube3/index.d.ts.map +1 -1
- package/dist/puzzles/cube3/moves.d.ts.map +1 -1
- package/dist/puzzles/cube3/moves.js +104 -18
- package/dist/puzzles/cube3/scrambler.d.ts +16 -1
- package/dist/puzzles/cube3/scrambler.d.ts.map +1 -1
- package/dist/puzzles/cube3/scrambler.js +1 -1
- package/dist/puzzles/cube3/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/browser-loader.js +48 -22
- package/dist/puzzles/cube3/solver/generated-assets.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/generated-assets.js +9 -3
- package/dist/puzzles/cube3/solver/index.d.ts +5 -3
- package/dist/puzzles/cube3/solver/index.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/index.js +2 -1
- package/dist/puzzles/cube3/solver/node-loader.js +9 -2
- package/dist/puzzles/cube3/solver/phase1.d.ts +37 -0
- package/dist/puzzles/cube3/solver/phase1.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/phase1.js +156 -15
- package/dist/puzzles/cube3/solver/phase2.d.ts +75 -0
- package/dist/puzzles/cube3/solver/phase2.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/phase2.js +279 -68
- package/dist/puzzles/cube3/solver/search-utils.d.ts +1 -1
- package/dist/puzzles/cube3/solver/search-utils.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/symmetry.d.ts +24 -0
- package/dist/puzzles/cube3/solver/symmetry.d.ts.map +1 -0
- package/dist/puzzles/cube3/solver/symmetry.js +74 -0
- package/dist/puzzles/cube3/solver/tables.d.ts +6 -1
- package/dist/puzzles/cube3/solver/tables.d.ts.map +1 -1
- package/dist/puzzles/cube3/solver/tables.js +14 -12
- package/dist/puzzles/cube3/validation.d.ts.map +1 -1
- package/dist/puzzles/cube3/validation.js +15 -7
- package/dist/puzzles/cube4/browser-worker-pool.d.ts +82 -0
- package/dist/puzzles/cube4/browser-worker-pool.d.ts.map +1 -0
- package/dist/puzzles/cube4/browser-worker-pool.js +205 -0
- package/dist/puzzles/cube4/browser-worker.d.ts +2 -0
- package/dist/puzzles/cube4/browser-worker.d.ts.map +1 -0
- package/dist/puzzles/cube4/browser-worker.js +31 -0
- package/dist/puzzles/cube4/index.d.ts +10 -2
- package/dist/puzzles/cube4/index.d.ts.map +1 -1
- package/dist/puzzles/cube4/index.js +6 -2
- package/dist/puzzles/cube4/moves.d.ts +5 -0
- package/dist/puzzles/cube4/moves.d.ts.map +1 -1
- package/dist/puzzles/cube4/moves.js +212 -11
- package/dist/puzzles/cube4/reduction/browser-loader.d.ts +29 -1
- package/dist/puzzles/cube4/reduction/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/browser-loader.js +227 -32
- package/dist/puzzles/cube4/reduction/center2.d.ts +44 -3
- package/dist/puzzles/cube4/reduction/center2.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/center2.js +152 -10
- package/dist/puzzles/cube4/reduction/edge3.d.ts +4 -0
- package/dist/puzzles/cube4/reduction/edge3.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/edge3.js +23 -3
- package/dist/puzzles/cube4/reduction/finish3.d.ts +53 -0
- package/dist/puzzles/cube4/reduction/finish3.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/finish3.js +393 -0
- package/dist/puzzles/cube4/reduction/generated/c3_pair_dist.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/center2-manifest.json +36 -0
- package/dist/puzzles/cube4/reduction/generated/center2-pruning-wide.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/hc-distances.bin +1 -0
- package/dist/puzzles/cube4/reduction/generated/hc-manifest.json +44 -0
- package/dist/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.d.ts +52 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/hc-pdb.js +220 -0
- package/dist/puzzles/cube4/reduction/node-loader.d.ts +15 -1
- package/dist/puzzles/cube4/reduction/node-loader.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/node-loader.js +199 -25
- package/dist/puzzles/cube4/reduction/pair-transversal.d.ts +28 -0
- package/dist/puzzles/cube4/reduction/pair-transversal.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/pair-transversal.js +107 -0
- package/dist/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
- package/dist/puzzles/cube4/reduction/phase3-search.d.ts +116 -7
- package/dist/puzzles/cube4/reduction/phase3-search.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/phase3-search.js +458 -32
- package/dist/puzzles/cube4/reduction/rotation-fix.d.ts +28 -0
- package/dist/puzzles/cube4/reduction/rotation-fix.d.ts.map +1 -0
- package/dist/puzzles/cube4/reduction/rotation-fix.js +212 -0
- package/dist/puzzles/cube4/reduction/solve.d.ts +172 -2
- package/dist/puzzles/cube4/reduction/solve.d.ts.map +1 -1
- package/dist/puzzles/cube4/reduction/solve.js +1201 -180
- package/dist/puzzles/cube4/scramble-cache.d.ts +93 -0
- package/dist/puzzles/cube4/scramble-cache.d.ts.map +1 -0
- package/dist/puzzles/cube4/scramble-cache.js +150 -0
- package/dist/puzzles/cube4/scrambler.d.ts +201 -6
- package/dist/puzzles/cube4/scrambler.d.ts.map +1 -1
- package/dist/puzzles/cube4/scrambler.js +414 -176
- package/dist/puzzles/cube4/state.d.ts.map +1 -1
- package/dist/puzzles/cube4/state.js +4 -1
- package/dist/puzzles/cube4/worker-pool.d.ts +139 -0
- package/dist/puzzles/cube4/worker-pool.d.ts.map +1 -0
- package/dist/puzzles/cube4/worker-pool.js +405 -0
- package/dist/puzzles/cube4/worker-protocol.d.ts +58 -0
- package/dist/puzzles/cube4/worker-protocol.d.ts.map +1 -0
- package/dist/puzzles/cube4/worker-protocol.js +58 -0
- package/dist/puzzles/cube4/worker.d.ts +26 -0
- package/dist/puzzles/cube4/worker.d.ts.map +1 -0
- package/dist/puzzles/cube4/worker.js +49 -0
- package/dist/puzzles/pyraminx/solver/browser-loader.d.ts +4 -8
- package/dist/puzzles/pyraminx/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/solver/browser-loader.js +44 -15
- package/dist/puzzles/pyraminx/solver/generated-assets.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/solver/generated-assets.js +8 -3
- package/dist/puzzles/pyraminx/solver/search.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/solver/search.js +3 -6
- package/dist/puzzles/pyraminx/solver/tables.d.ts +6 -0
- package/dist/puzzles/pyraminx/solver/tables.d.ts.map +1 -1
- package/dist/puzzles/pyraminx/solver/tables.js +17 -0
- package/dist/puzzles/shared/compressed-fetch.d.ts +37 -1
- package/dist/puzzles/shared/compressed-fetch.d.ts.map +1 -1
- package/dist/puzzles/shared/compressed-fetch.js +226 -31
- package/dist/puzzles/shared/load-once.d.ts +16 -0
- package/dist/puzzles/shared/load-once.d.ts.map +1 -0
- package/dist/puzzles/shared/load-once.js +11 -0
- package/dist/puzzles/skewb/solver/browser-loader.d.ts +4 -11
- package/dist/puzzles/skewb/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/skewb/solver/browser-loader.js +44 -16
- package/dist/puzzles/skewb/solver/generated-assets.d.ts.map +1 -1
- package/dist/puzzles/skewb/solver/generated-assets.js +8 -3
- package/dist/puzzles/skewb/solver/search.js +3 -3
- package/dist/puzzles/skewb/solver/tables.d.ts +6 -0
- package/dist/puzzles/skewb/solver/tables.d.ts.map +1 -1
- package/dist/puzzles/skewb/solver/tables.js +17 -0
- package/dist/puzzles/sq1/solver/browser-loader.d.ts.map +1 -1
- package/dist/puzzles/sq1/solver/browser-loader.js +58 -26
- package/dist-cjs/core/api.js +10 -2
- package/dist-cjs/puzzles/cube2/solver/browser-loader.js +42 -14
- package/dist-cjs/puzzles/cube2/solver/generated-assets.js +8 -3
- package/dist-cjs/puzzles/cube2/solver/search.js +2 -2
- package/dist-cjs/puzzles/cube2/solver/tables.js +17 -3
- package/dist-cjs/puzzles/cube3/moves.js +104 -18
- package/dist-cjs/puzzles/cube3/scrambler.js +1 -1
- package/dist-cjs/puzzles/cube3/solver/browser-loader.js +48 -22
- package/dist-cjs/puzzles/cube3/solver/generated-assets.js +9 -3
- package/dist-cjs/puzzles/cube3/solver/index.js +8 -1
- package/dist-cjs/puzzles/cube3/solver/node-loader.js +9 -2
- package/dist-cjs/puzzles/cube3/solver/phase1.js +157 -15
- package/dist-cjs/puzzles/cube3/solver/phase2.js +276 -65
- package/dist-cjs/puzzles/cube3/solver/symmetry.js +80 -0
- package/dist-cjs/puzzles/cube3/solver/tables.js +14 -12
- package/dist-cjs/puzzles/cube3/validation.js +15 -7
- package/dist-cjs/puzzles/cube4/browser-worker-pool.js +211 -0
- package/dist-cjs/puzzles/cube4/index.js +23 -1
- package/dist-cjs/puzzles/cube4/moves.js +213 -11
- package/dist-cjs/puzzles/cube4/reduction/browser-loader.js +227 -32
- package/dist-cjs/puzzles/cube4/reduction/center2.js +155 -10
- package/dist-cjs/puzzles/cube4/reduction/edge3.js +24 -3
- package/dist-cjs/puzzles/cube4/reduction/finish3.js +398 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/c3_pair_dist.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center2-manifest.json +36 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/center2-pruning-wide.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/hc-distances.bin +1 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/hc-manifest.json +44 -0
- package/dist-cjs/puzzles/cube4/reduction/generated/hc-move.bin +0 -0
- package/dist-cjs/puzzles/cube4/reduction/hc-pdb.js +232 -0
- package/dist-cjs/puzzles/cube4/reduction/node-loader.js +200 -25
- package/dist-cjs/puzzles/cube4/reduction/pair-transversal.js +112 -0
- package/dist-cjs/puzzles/cube4/reduction/pairing-coordinate.js +5 -5
- package/dist-cjs/puzzles/cube4/reduction/phase3-search.js +460 -33
- package/dist-cjs/puzzles/cube4/reduction/rotation-fix.js +216 -0
- package/dist-cjs/puzzles/cube4/reduction/solve.js +1203 -172
- package/dist-cjs/puzzles/cube4/scramble-cache.js +156 -0
- package/dist-cjs/puzzles/cube4/scrambler.js +416 -174
- package/dist-cjs/puzzles/cube4/state.js +4 -1
- package/dist-cjs/puzzles/cube4/worker-pool.js +447 -0
- package/dist-cjs/puzzles/cube4/worker-protocol.js +62 -0
- package/dist-cjs/puzzles/pyraminx/solver/browser-loader.js +44 -15
- package/dist-cjs/puzzles/pyraminx/solver/generated-assets.js +8 -3
- package/dist-cjs/puzzles/pyraminx/solver/search.js +2 -5
- package/dist-cjs/puzzles/pyraminx/solver/tables.js +18 -1
- package/dist-cjs/puzzles/shared/compressed-fetch.js +229 -31
- package/dist-cjs/puzzles/shared/load-once.js +14 -0
- package/dist-cjs/puzzles/skewb/solver/browser-loader.js +44 -16
- package/dist-cjs/puzzles/skewb/solver/generated-assets.js +8 -3
- package/dist-cjs/puzzles/skewb/solver/search.js +2 -2
- package/dist-cjs/puzzles/skewb/solver/tables.js +18 -1
- package/dist-cjs/puzzles/sq1/solver/browser-loader.js +58 -26
- package/docs/development.md +19 -7
- package/package.json +17 -7
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Background prefetch buffer for 4x4 scrambles — the Node-side analogue of
|
|
4
|
+
* TNoodle's `ScrambleCacher`.
|
|
5
|
+
*
|
|
6
|
+
* The cache keeps up to `size` scrambles generating AHEAD of consumption:
|
|
7
|
+
* - `take()` shifts the OLDEST slot; if it is already settled it resolves
|
|
8
|
+
* immediately (no waiting for later slots), otherwise it awaits only
|
|
9
|
+
* that slot. Order is FIFO of START (not of completion), so a seeded
|
|
10
|
+
* stream hands out `seed:0`, `seed:1`, … in order even when the
|
|
11
|
+
* underlying generator finishes out of order (parallel pool).
|
|
12
|
+
* - every shift triggers a refill, so the buffer repopulates in the
|
|
13
|
+
* background — wire `generate: (o) => pool.generate(o)` and the refill
|
|
14
|
+
* itself runs across worker threads (see the pool integration test).
|
|
15
|
+
* - failures are FIRST-CLASS slots: a slot that rejects is delivered as a
|
|
16
|
+
* rejection to the next `take()` (consumed exactly once) and the cache
|
|
17
|
+
* keeps going with the following slots. Every slot promise is wrapped
|
|
18
|
+
* at creation so a background failure can NEVER surface as an
|
|
19
|
+
* unhandledRejection, and `take()` never hangs: slots always settle
|
|
20
|
+
* (the generator contract is "settles eventually").
|
|
21
|
+
* - `dispose()` stops refilling and drops buffered slots. In-flight
|
|
22
|
+
* generations are left to settle silently (results discarded). There
|
|
23
|
+
* are NO timers anywhere, so a disposed (or even forgotten) cache never
|
|
24
|
+
* keeps a process alive.
|
|
25
|
+
*
|
|
26
|
+
* Seeding: when `options.seed` is defined, slot n is generated with
|
|
27
|
+
* `${seed}:${n}` — byte-identical to core `generateScrambles("444", …)`
|
|
28
|
+
* for any count > 1 (slot 0 ↔ item 0 of a batch). Without a seed every
|
|
29
|
+
* slot uses the base options unchanged (fresh randomness).
|
|
30
|
+
*/
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.Cube4ScrambleCache = void 0;
|
|
33
|
+
exports.deriveCube4StreamOptions = deriveCube4StreamOptions;
|
|
34
|
+
exports.createCube4ScrambleCache = createCube4ScrambleCache;
|
|
35
|
+
const scrambler_js_1 = require("./scrambler.js");
|
|
36
|
+
/**
|
|
37
|
+
* Stream slot derivation (cache analogue of core's batch derivation).
|
|
38
|
+
* Exported for tests and for hosts that precompute the same sequence.
|
|
39
|
+
*/
|
|
40
|
+
function deriveCube4StreamOptions(options, index) {
|
|
41
|
+
if (options.seed === undefined)
|
|
42
|
+
return options;
|
|
43
|
+
return { ...options, seed: `${options.seed}:${index}` };
|
|
44
|
+
}
|
|
45
|
+
class Cube4ScrambleCache {
|
|
46
|
+
capacity;
|
|
47
|
+
baseOptions;
|
|
48
|
+
generator;
|
|
49
|
+
/** FIFO of slots (start order); settled or still pending. */
|
|
50
|
+
slots = [];
|
|
51
|
+
nextIndex = 0;
|
|
52
|
+
disposed = false;
|
|
53
|
+
constructor(options = {}) {
|
|
54
|
+
const size = options.size ?? 4;
|
|
55
|
+
if (!Number.isInteger(size) || size < 1) {
|
|
56
|
+
throw new RangeError(`[cube4] cache size must be an integer >= 1 (got ${size}).`);
|
|
57
|
+
}
|
|
58
|
+
this.capacity = size;
|
|
59
|
+
this.baseOptions = options.options ?? {};
|
|
60
|
+
this.generator = options.generate ?? scrambler_js_1.generateCube4Scramble;
|
|
61
|
+
// Prefetch starts immediately: that is the point of constructing a cache.
|
|
62
|
+
this.pump();
|
|
63
|
+
}
|
|
64
|
+
/** Configured buffer capacity. */
|
|
65
|
+
get size() {
|
|
66
|
+
return this.capacity;
|
|
67
|
+
}
|
|
68
|
+
/** Slots currently buffered (settled + still generating). */
|
|
69
|
+
get buffered() {
|
|
70
|
+
return this.slots.length;
|
|
71
|
+
}
|
|
72
|
+
/** Buffered slots that have already settled (ready for an instant take()). */
|
|
73
|
+
get ready() {
|
|
74
|
+
let count = 0;
|
|
75
|
+
for (const carrier of this.slots)
|
|
76
|
+
if (carrier.slot !== undefined)
|
|
77
|
+
count++;
|
|
78
|
+
return count;
|
|
79
|
+
}
|
|
80
|
+
/** Slots currently generating in the background. */
|
|
81
|
+
get inFlight() {
|
|
82
|
+
let count = 0;
|
|
83
|
+
for (const carrier of this.slots)
|
|
84
|
+
if (carrier.slot === undefined)
|
|
85
|
+
count++;
|
|
86
|
+
return count;
|
|
87
|
+
}
|
|
88
|
+
get isDisposed() {
|
|
89
|
+
return this.disposed;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Resolves once the buffer holds `size` settled results (i.e. a
|
|
93
|
+
* subsequent `take()` is served instantly). Safe to call at any time;
|
|
94
|
+
* rejects only if called after `dispose()`.
|
|
95
|
+
*/
|
|
96
|
+
warmup() {
|
|
97
|
+
if (this.disposed) {
|
|
98
|
+
return Promise.reject(new Error("[cube4] scramble cache is disposed (warmup)."));
|
|
99
|
+
}
|
|
100
|
+
this.pump();
|
|
101
|
+
return Promise.all(this.slots.map((carrier) => carrier.promise)).then(() => undefined);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Next scramble in FIFO order. Instant when the front slot is settled;
|
|
105
|
+
* otherwise waits only for the front slot (never for later ones).
|
|
106
|
+
* A failed background generation surfaces here as a rejection — exactly
|
|
107
|
+
* once — and the cache continues with subsequent slots.
|
|
108
|
+
*/
|
|
109
|
+
take() {
|
|
110
|
+
if (this.disposed) {
|
|
111
|
+
return Promise.reject(new Error("[cube4] scramble cache is disposed (take)."));
|
|
112
|
+
}
|
|
113
|
+
const carrier = this.slots.shift();
|
|
114
|
+
this.pump(); // refill BEFORE awaiting, so generation overlaps consumption
|
|
115
|
+
if (carrier === undefined) {
|
|
116
|
+
// Only reachable when capacity was somehow drained concurrently;
|
|
117
|
+
// generate one on the spot rather than hang.
|
|
118
|
+
return this.generateNow();
|
|
119
|
+
}
|
|
120
|
+
return carrier.promise.then((slot) => {
|
|
121
|
+
if (slot.ok)
|
|
122
|
+
return slot.result;
|
|
123
|
+
throw slot.error;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Stops prefetching, drops buffered slots and ignores in-flight
|
|
128
|
+
* completions. No timers are involved, so nothing can keep a process
|
|
129
|
+
* alive afterwards. Idempotent.
|
|
130
|
+
*/
|
|
131
|
+
dispose() {
|
|
132
|
+
this.disposed = true;
|
|
133
|
+
this.slots.length = 0;
|
|
134
|
+
}
|
|
135
|
+
// ── internals ────────────────────────────────────────────────────────
|
|
136
|
+
pump() {
|
|
137
|
+
while (!this.disposed && this.slots.length < this.capacity) {
|
|
138
|
+
const index = this.nextIndex++;
|
|
139
|
+
const promise = this.generator(deriveCube4StreamOptions(this.baseOptions, index)).then((result) => ({ ok: true, result }), (error) => ({ ok: false, error }));
|
|
140
|
+
const carrier = { promise, slot: undefined };
|
|
141
|
+
void promise.then((slot) => {
|
|
142
|
+
carrier.slot = slot;
|
|
143
|
+
});
|
|
144
|
+
this.slots.push(carrier);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
generateNow() {
|
|
148
|
+
const index = this.nextIndex++;
|
|
149
|
+
return this.generator(deriveCube4StreamOptions(this.baseOptions, index));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.Cube4ScrambleCache = Cube4ScrambleCache;
|
|
153
|
+
/** Convenience factory mirroring the other cube4 constructors. */
|
|
154
|
+
function createCube4ScrambleCache(options = {}) {
|
|
155
|
+
return new Cube4ScrambleCache(options);
|
|
156
|
+
}
|