@serfab/quereus-plugin-sereus 0.11.0 → 0.13.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/dist/cached-storage.d.ts +45 -16
- package/dist/cached-storage.js +87 -34
- package/dist/cached-storage.js.map +1 -1
- package/dist/cluster-size.d.ts +175 -7
- package/dist/cluster-size.js +207 -7
- package/dist/cluster-size.js.map +1 -1
- package/dist/compose-strand.d.ts +14 -1
- package/dist/compose-strand.js +83 -33
- package/dist/compose-strand.js.map +1 -1
- package/dist/connect-browser.js +2 -1
- package/dist/connect-browser.js.map +1 -1
- package/dist/connect.js +2 -1
- package/dist/connect.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/plugin-browser.js +78614 -78119
- package/dist/plugin-browser.js.map +4 -4
- package/dist/strand-schema.d.ts +4 -3
- package/dist/strand-schema.js +74 -23
- package/dist/strand-schema.js.map +1 -1
- package/package.json +8 -8
- package/src/cached-storage.ts +105 -34
- package/src/cluster-size.ts +455 -248
- package/src/compose-strand.ts +396 -323
- package/src/connect-browser.ts +58 -57
- package/src/connect.ts +39 -38
- package/src/index.ts +4 -1
- package/src/strand-schema.ts +74 -23
package/dist/cluster-size.js
CHANGED
|
@@ -7,7 +7,12 @@ export const MIN_CLUSTER_SIZE = 2;
|
|
|
7
7
|
/**
|
|
8
8
|
* How many nodes each block of the **control** (cadre membership) database is replicated
|
|
9
9
|
* to. Chosen to exceed any party's node count, so in practice every control block lands
|
|
10
|
-
* on every member of the party.
|
|
10
|
+
* on every member of the party. Cohort width alone only delivers that for blocks written
|
|
11
|
+
* while the members were serving the network: a block committed while the writer was
|
|
12
|
+
* alone (the founder's genesis above all — collection headers are written once and never
|
|
13
|
+
* revised) has a cohort of one, and it reaches later joiners through cadre-core's
|
|
14
|
+
* peer-join block catch-up (`peer-join-backfill.ts`, membership-gated on the control
|
|
15
|
+
* network), not through this breadth.
|
|
11
16
|
*
|
|
12
17
|
* **Why full replication here.** Every control node reads the whole control database —
|
|
13
18
|
* membership, peer addresses, the strand list — so a member left out of a block's cohort is
|
|
@@ -90,6 +95,20 @@ export const CONTROL_REPLICATION_BREADTH = 16;
|
|
|
90
95
|
* is what the corroboration floor is asking. See Optimystic's `cluster/cluster-policy.ts`
|
|
91
96
|
* ("Why two size yardsticks, not one") and `corroboratorCapacity` in `cluster/quorum-restore.ts`.
|
|
92
97
|
*
|
|
98
|
+
* **`assumedClusterSize` is now the ADMISSION yardstick.** Since Optimystic grew
|
|
99
|
+
* `repairCorroborationClusterSize` (see {@link controlClusterPolicy}), the repair corroboration
|
|
100
|
+
* floor prefers that separate declaration and reads this field only when nothing was declared —
|
|
101
|
+
* the unknown-machine-count path, where the paragraph above still describes what it does. So on
|
|
102
|
+
* every path where the count IS known, the 2 here governs one consumer: the membership admission
|
|
103
|
+
* gate's low-confidence fallback path. Leaving
|
|
104
|
+
* it at 2 is deliberate and must NOT be "fixed" to match the repair yardstick. Raising it would
|
|
105
|
+
* make the gate demand `ceil(0.75 x N)` DECLARED peers before it admits a coordinator's peer
|
|
106
|
+
* set on that path, and a Cadre party is phones and laptops: it cannot promise that three
|
|
107
|
+
* quarters of its enrolled machines are awake at any moment, so a party of eight with three
|
|
108
|
+
* awake would stop transacting entirely. The repair yardstick has no such cost (it gates only
|
|
109
|
+
* whether this node believes a repair answer), which is exactly why the two are now separate
|
|
110
|
+
* numbers rather than one.
|
|
111
|
+
*
|
|
93
112
|
* The `satisfies` is load-bearing: without it a mistyped or obsolete key would compile at both
|
|
94
113
|
* this definition and every consumer, because TypeScript only excess-property-checks fresh
|
|
95
114
|
* object literals, not a shared constant handed to `clusterPolicy`.
|
|
@@ -125,6 +144,13 @@ export const CONTROL_CLUSTER_POLICY = Object.freeze({
|
|
|
125
144
|
* phones and laptops is the ordinary case, not the rare one. Six buys no more fault tolerance
|
|
126
145
|
* than four and costs more overfetch (see the NOTE below).
|
|
127
146
|
*
|
|
147
|
+
* **Exercised at four machines** by `integration-tests`'
|
|
148
|
+
* `scenarios/strand-two-party-two-machine.integration.ts`, the only scenario that runs a
|
|
149
|
+
* strand at this breadth. It shows a write committing while one of the four machines is off.
|
|
150
|
+
* It does NOT distinguish that from a commit on a cohort downsized to the three live holders
|
|
151
|
+
* (`allowDownsize` in {@link STRAND_CLUSTER_POLICY}), so the table row above remains reasoned
|
|
152
|
+
* arithmetic with an end-to-end existence proof under it, not a measurement of cohort width.
|
|
153
|
+
*
|
|
128
154
|
* **It is also a correctness floor, not only a durability one — but the floor is measured in
|
|
129
155
|
* machines, not in this number.** A node that has fallen behind and can ask exactly one peer
|
|
130
156
|
* whether it is current has Optimystic accept that single answer as the cluster's truth
|
|
@@ -133,12 +159,24 @@ export const CONTROL_CLUSTER_POLICY = Object.freeze({
|
|
|
133
159
|
* honestly reports the stale revision, the reader concludes it is current, and re-arms its
|
|
134
160
|
* repair window forever. Measured on the control-DB replication scenario: 4 failures in 10 runs
|
|
135
161
|
* at breadth 2, 0 in 20 at breadth 3, 0 in 10 at breadth 8. What lifts the floor off a single
|
|
136
|
-
* voter is a
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
162
|
+
* voter is a third machine **or a declaration that there are three** — not a wider target.
|
|
163
|
+
* `corroboratorCapacity` takes the max of the cohort peers actually present and the declared
|
|
164
|
+
* repair yardstick, so raising *this* number (the replication breadth) does nothing: the
|
|
165
|
+
* yardstick is a separate declaration, and **a strand node makes no such declaration today**.
|
|
166
|
+
* The control network derives one from the party's enrolled machines
|
|
167
|
+
* ({@link controlClusterPolicy}), which is exact there because every enrolled machine runs the
|
|
168
|
+
* control node. A strand has no equivalent count: it launches only on machines whose embedder
|
|
169
|
+
* registered its sApp config, and reusing the party count over-declares — which is worse than
|
|
170
|
+
* declaring nothing, because at a yardstick of three or more the corroboration floor is pinned
|
|
171
|
+
* at two peers and a strand that can field only one could then never repair at all. So every
|
|
172
|
+
* strand runs {@link STRAND_CLUSTER_POLICY} unchanged and takes the single-voter exposure
|
|
173
|
+
* whenever its cohort view shrinks to one peer. The underlying Optimystic behaviour is unfixed
|
|
174
|
+
* (`backlog/debt-read-repair-single-voter-corroboration`) and the per-strand serving count that
|
|
175
|
+
* would let a strand declare honestly is `backlog/feat-strand-yardstick-from-serving-machines`
|
|
176
|
+
* — its seam ({@link strandClusterPolicy}'s `servingMachines`, threaded through
|
|
177
|
+
* `StartStrandConfig.servingMachines`) is already in place and fed by nothing. Raising this
|
|
178
|
+
* number does not buy the way out; a machine, or an honest declaration of the machines actually
|
|
179
|
+
* serving the strand, does.
|
|
142
180
|
*
|
|
143
181
|
* **Why not derived from the party or member count.** The strand's `Member` rows live *in* the
|
|
144
182
|
* strand database, which runs on the strand libp2p node, whose cluster size is frozen at
|
|
@@ -205,6 +243,17 @@ export const DEFAULT_STRAND_CLUSTER_SIZE = 4;
|
|
|
205
243
|
* number, so the relaxed branch is reachable only by a cohort that is genuinely that small. See
|
|
206
244
|
* Optimystic's `cluster/cluster-policy.ts` ("Why two size yardsticks, not one").
|
|
207
245
|
*
|
|
246
|
+
* `assumedClusterSize` also carries the ADMISSION yardstick, and on the strand path it carries
|
|
247
|
+
* BOTH jobs today. Optimystic prefers a separately declared
|
|
248
|
+
* `repairCorroborationClusterSize` for the repair floor and falls back to this field only when
|
|
249
|
+
* nothing was declared — which, for a strand, is always: no per-strand serving count exists yet,
|
|
250
|
+
* so {@link strandClusterPolicy} declares nothing and the 2 here governs the repair floor
|
|
251
|
+
* exactly as the paragraph above describes, alongside the membership admission gate's
|
|
252
|
+
* low-confidence fallback. Do not raise it if a strand yardstick ever does get declared
|
|
253
|
+
* (`backlog/feat-strand-yardstick-from-serving-machines`): a strand shared between phones cannot
|
|
254
|
+
* promise that `ceil(0.75 x N)` of its machines are awake, and the admission gate would refuse
|
|
255
|
+
* its writes. Same reason and same warning as {@link CONTROL_CLUSTER_POLICY}'s.
|
|
256
|
+
*
|
|
208
257
|
* The `satisfies` is load-bearing for the same reason as {@link CONTROL_CLUSTER_POLICY}'s.
|
|
209
258
|
*/
|
|
210
259
|
export const STRAND_CLUSTER_POLICY = Object.freeze({
|
|
@@ -237,4 +286,155 @@ export function resolveStrandClusterSize(configured) {
|
|
|
237
286
|
}
|
|
238
287
|
return configured;
|
|
239
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* The repair yardstick to declare for a network, from the machines that SERVE that network and
|
|
291
|
+
* the breadth it replicates to.
|
|
292
|
+
*
|
|
293
|
+
* ## What this number does
|
|
294
|
+
*
|
|
295
|
+
* Optimystic's block repair (read-repair and reconcile) asks a block's cohort for the newest
|
|
296
|
+
* revision and trusts an answer only when enough independent peers agree on it. "Enough" is
|
|
297
|
+
* measured against a **declared** number rather than the peers currently visible — deliberately,
|
|
298
|
+
* because the visible set comes from unauthenticated routing, and a partition (or an attacker
|
|
299
|
+
* with routing influence) can shrink it. `clusterPolicy.repairCorroborationClusterSize` is that
|
|
300
|
+
* declaration; it moves the repair yardstick ALONE, leaving
|
|
301
|
+
* {@link CONTROL_CLUSTER_POLICY}'s / {@link STRAND_CLUSTER_POLICY}'s `assumedClusterSize` — the
|
|
302
|
+
* membership admission gate's yardstick — untouched. Optimystic resolves
|
|
303
|
+
* `repairCorroborationClusterSize -> assumedClusterSize -> clusterSize`, and a value that is not
|
|
304
|
+
* a positive integer falls THROUGH to the next term rather than being clamped, which is why the
|
|
305
|
+
* builders below refuse to pass a degenerate count at all.
|
|
306
|
+
*
|
|
307
|
+
* ## The arithmetic, and why the formula is what it is
|
|
308
|
+
*
|
|
309
|
+
* Three consumers read the resolved yardstick `N`. With `p` = cohort peers currently visible
|
|
310
|
+
* (self excluded) and Optimystic's `CORROBORATION_FLOOR` = 2:
|
|
311
|
+
*
|
|
312
|
+
* - **Repair corroboration floor** (`corroboratorCapacity` / `quorumSize` in
|
|
313
|
+
* `db-p2p/src/cluster/quorum-restore.ts`): capacity is `max(p, N - 1)` and the floor is
|
|
314
|
+
* `max(1, min(2, capacity))`. So `N = 1` and `N = 2` behave IDENTICALLY at every `p` — both
|
|
315
|
+
* leave the floor at a single voter whenever `p <= 1`. `N >= 3` pins the floor at two
|
|
316
|
+
* corroborators unconditionally, including when the view has shrunk to one peer. That is the
|
|
317
|
+
* entire point of declaring. `N` above 3 raises nothing further (the `min(2, ...)` caps it), so
|
|
318
|
+
* a larger declaration buys only honesty, never more repair.
|
|
319
|
+
* - **Commit freshness window** (`CoordinatorRepo.commitQuorumRulesOutRivals`): `fullCohortSize`
|
|
320
|
+
* is `max(observed cohort, N)`, and a local commit arms the lazy read-repair window only when
|
|
321
|
+
* `approvals > fullCohortSize / 2`. Here a larger `N` is NOT free — see the NOTE below.
|
|
322
|
+
* - The `repair-fault-tolerance` startup advisory — log text only.
|
|
323
|
+
*
|
|
324
|
+
* Hence `max(MIN_CLUSTER_SIZE, min(servingMachines, replicationBreadth))`, two clamps each for
|
|
325
|
+
* a stated reason:
|
|
326
|
+
*
|
|
327
|
+
* - **Capped at the replication breadth**, because a block only ever lives on
|
|
328
|
+
* `min(breadth, machines serving)` machines. A party of eight running strands at
|
|
329
|
+
* {@link DEFAULT_STRAND_CLUSTER_SIZE} has a cohort of four; declaring eight would make
|
|
330
|
+
* `approvals > 4` unsatisfiable (a super-majority of four is three), so the freshness window
|
|
331
|
+
* would never arm for any strand commit, forever — and buy nothing on repair, whose floor is
|
|
332
|
+
* already at its cap at four. Declare the machines that can hold the block, not the machines
|
|
333
|
+
* that exist.
|
|
334
|
+
* - **Floored at {@link MIN_CLUSTER_SIZE}**, so this can only ever RAISE the declared number
|
|
335
|
+
* relative to the un-derived constants. A node that authorizes nobody is a genuine
|
|
336
|
+
* founder-alone party, but it is equally a freshly seeded node whose membership rows have not
|
|
337
|
+
* replicated yet, or one whose trusted-owner anchor is empty — and this node cannot tell those
|
|
338
|
+
* apart. Declaring 1 is safety-neutral for repair (identical to 2 at every `p`, per the table
|
|
339
|
+
* above) but it WOULD let a solo commit arm the freshness window, which is wrong if the "solo"
|
|
340
|
+
* reading came from stale local records. Lifting that floor for a node that can prove it is
|
|
341
|
+
* genuinely alone is separate work: `backlog/feat-solo-node-arms-its-own-freshness-window`.
|
|
342
|
+
*
|
|
343
|
+
* The yardstick is per-node and protects only that node's own reads — no node refuses another
|
|
344
|
+
* anything over it — so two members disagreeing (one has replicated a new `CadrePeer` row, one
|
|
345
|
+
* has not) is harmless by construction, not a race to close.
|
|
346
|
+
*
|
|
347
|
+
* ## The contract: callers pass machines that SERVE this network, or nothing at all
|
|
348
|
+
*
|
|
349
|
+
* Over-declaring is not merely wasteful, it is unsafe in the availability direction: at
|
|
350
|
+
* `N >= 3` the corroboration floor is pinned at two peers, so a cohort that can only ever
|
|
351
|
+
* field one peer can never repair at all (`cluster-fetch:no-quorum`), where a declaration of
|
|
352
|
+
* 2 would have let its single peer answer. So the number a caller passes must be the machines
|
|
353
|
+
* that actually serve the network in question — never a broader population that merely bounds
|
|
354
|
+
* it from above, and never a guess. A caller with no trustworthy count passes nothing, which
|
|
355
|
+
* the builders below turn into "declare no yardstick at all".
|
|
356
|
+
*
|
|
357
|
+
* The CONTROL network satisfies this from the party's enrolled machines, because every enrolled
|
|
358
|
+
* machine runs the control node by construction: there, enrolled IS serving
|
|
359
|
+
* ({@link controlClusterPolicy}, fed by cadre-core's `enrolled-machine-store.ts`). A STRAND does
|
|
360
|
+
* not — it launches only on machines whose embedder registered its sApp config
|
|
361
|
+
* (`CadreNode.addStrand`), so a closed strand shared by two machines of a three-machine party is
|
|
362
|
+
* served by two, and declaring three would be exactly the unsafe over-declaration above. No
|
|
363
|
+
* authenticated per-strand serving count exists yet, so strand nodes declare NOTHING and run the
|
|
364
|
+
* frozen {@link STRAND_CLUSTER_POLICY} — keeping the known, upstream-tracked single-voter
|
|
365
|
+
* exposure (`backlog/debt-read-repair-single-voter-corroboration`) rather than risking the
|
|
366
|
+
* cannot-repair-at-all failure. Building that count:
|
|
367
|
+
* `backlog/feat-strand-yardstick-from-serving-machines`.
|
|
368
|
+
*
|
|
369
|
+
* Both arguments must be positive integers; the builders below sanitize before calling, and
|
|
370
|
+
* a degenerate value here propagates (`NaN` in, `NaN` out) rather than being clamped.
|
|
371
|
+
*
|
|
372
|
+
* NOTE: on a party of three or more machines where fewer than half are awake, a commit reaches a
|
|
373
|
+
* downsized cohort and no longer arms the freshness window, so each such block's next read costs
|
|
374
|
+
* one cohort consult per read-repair window instead of trusting the local commit. That is the
|
|
375
|
+
* correct reading of the honest number — a commit that reached two of five machines genuinely
|
|
376
|
+
* does not rule out a rival quorum, and arming it today is a consequence of under-declaring — and
|
|
377
|
+
* the cost is bounded at one consult per block per window by the read path's solo-self-skip exit.
|
|
378
|
+
* NOT measured under load. If a large, mostly-hibernating party's read path ever shows up as
|
|
379
|
+
* slow, this is the first thing to look at.
|
|
380
|
+
*/
|
|
381
|
+
export function resolveRepairYardstick(servingMachines, replicationBreadth) {
|
|
382
|
+
return Math.max(MIN_CLUSTER_SIZE, Math.min(servingMachines, replicationBreadth));
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* A serving-machine count as a usable number, or `undefined` for "this node does not know".
|
|
386
|
+
* Anything that is not a positive integer is unknown rather than clamped: Optimystic itself
|
|
387
|
+
* treats a degenerate declaration as absent, so silently rounding one here would hide a caller
|
|
388
|
+
* bug behind a number nobody chose.
|
|
389
|
+
*/
|
|
390
|
+
function asKnownMachineCount(servingMachines) {
|
|
391
|
+
return servingMachines !== undefined
|
|
392
|
+
&& Number.isInteger(servingMachines)
|
|
393
|
+
&& servingMachines >= 1
|
|
394
|
+
? servingMachines
|
|
395
|
+
: undefined;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* {@link CONTROL_CLUSTER_POLICY} with the repair yardstick declared from `enrolledMachines`
|
|
399
|
+
* (see {@link resolveRepairYardstick}); the frozen base object ITSELF when the count is unknown,
|
|
400
|
+
* so the cold path is provably today's behaviour and identity assertions keep holding.
|
|
401
|
+
*
|
|
402
|
+
* The parameter keeps the name `enrolledMachines`, unlike {@link strandClusterPolicy}'s, because
|
|
403
|
+
* for the CONTROL network the two quantities are one and the same by construction: every
|
|
404
|
+
* enrolled machine runs the control node, so the machines enrolled in the party ARE the machines
|
|
405
|
+
* serving this network.
|
|
406
|
+
*/
|
|
407
|
+
export function controlClusterPolicy(enrolledMachines) {
|
|
408
|
+
const known = asKnownMachineCount(enrolledMachines);
|
|
409
|
+
if (known === undefined) {
|
|
410
|
+
return CONTROL_CLUSTER_POLICY;
|
|
411
|
+
}
|
|
412
|
+
return Object.freeze({
|
|
413
|
+
...CONTROL_CLUSTER_POLICY,
|
|
414
|
+
repairCorroborationClusterSize: resolveRepairYardstick(known, CONTROL_REPLICATION_BREADTH)
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* {@link STRAND_CLUSTER_POLICY} with the repair yardstick declared from `servingMachines` — the
|
|
419
|
+
* machines that serve THIS strand — and this strand's own `clusterSize` (already resolved by
|
|
420
|
+
* {@link resolveStrandClusterSize}, so it is at least {@link MIN_CLUSTER_SIZE} and the formula's
|
|
421
|
+
* two clamps can never cross); the frozen base object ITSELF when the count is unknown.
|
|
422
|
+
*
|
|
423
|
+
* **The unknown path is the production path today.** No authenticated per-strand serving count
|
|
424
|
+
* exists, and the party's enrolled-machine count is emphatically not one (see
|
|
425
|
+
* {@link resolveRepairYardstick}'s contract section), so cadre-core passes nothing and every
|
|
426
|
+
* strand node runs the frozen constant. The parameter and its threading through
|
|
427
|
+
* `StartStrandConfig.servingMachines` stay in place as the seam that
|
|
428
|
+
* `backlog/feat-strand-yardstick-from-serving-machines` plugs a real count into.
|
|
429
|
+
*/
|
|
430
|
+
export function strandClusterPolicy(clusterSize, servingMachines) {
|
|
431
|
+
const known = asKnownMachineCount(servingMachines);
|
|
432
|
+
if (known === undefined) {
|
|
433
|
+
return STRAND_CLUSTER_POLICY;
|
|
434
|
+
}
|
|
435
|
+
return Object.freeze({
|
|
436
|
+
...STRAND_CLUSTER_POLICY,
|
|
437
|
+
repairCorroborationClusterSize: resolveRepairYardstick(known, clusterSize)
|
|
438
|
+
});
|
|
439
|
+
}
|
|
240
440
|
//# sourceMappingURL=cluster-size.js.map
|
package/dist/cluster-size.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cluster-size.js","sourceRoot":"","sources":["../src/cluster-size.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC
|
|
1
|
+
{"version":3,"file":"cluster-size.js","sourceRoot":"","sources":["../src/cluster-size.ts"],"names":[],"mappings":"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"}
|
package/dist/compose-strand.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Database, VTablePluginInfo, FunctionPluginInfo, CollationPluginInfo } from '@quereus/quereus';
|
|
2
2
|
import type { Libp2p } from '@libp2p/interface';
|
|
3
|
-
import type { IRawStorage } from '@optimystic/db-p2p';
|
|
3
|
+
import type { IRawStorage, NodeOptions } from '@optimystic/db-p2p';
|
|
4
4
|
import type { StrandConnectionOptions, SereusPluginResult, StrandTransactor } from './types.js';
|
|
5
5
|
/** Registration shape shared by the crypto and optimystic plugin results. */
|
|
6
6
|
interface PluginRegistrations {
|
|
@@ -29,6 +29,19 @@ export interface CreateNodeContext {
|
|
|
29
29
|
* default of 10, which gates writes on any smaller party.
|
|
30
30
|
*/
|
|
31
31
|
clusterSize: number;
|
|
32
|
+
/**
|
|
33
|
+
* The strand cluster policy, resolved here so no platform has to remember it.
|
|
34
|
+
* Pass it to `createLibp2pNode` verbatim.
|
|
35
|
+
*
|
|
36
|
+
* Omitting it does NOT fall back to something equivalent: Optimystic then computes
|
|
37
|
+
* its read-repair corroboration floor against `clusterSize` instead of against
|
|
38
|
+
* {@link STRAND_CLUSTER_POLICY}'s `assumedClusterSize`, which is a stricter demand
|
|
39
|
+
* than a two-machine strand can meet — so repair of a damaged block gives up where
|
|
40
|
+
* it would otherwise succeed. That is the same defect class that took the *control*
|
|
41
|
+
* network's e2e suite down before `42cd12c`; see `cluster-size.ts` for the reasoning
|
|
42
|
+
* written out in full.
|
|
43
|
+
*/
|
|
44
|
+
clusterPolicy: NonNullable<NodeOptions['clusterPolicy']>;
|
|
32
45
|
/** Resolved persistent storage to back the node, if any. */
|
|
33
46
|
storage?: IRawStorage;
|
|
34
47
|
}
|
package/dist/compose-strand.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
2
|
import optimysticPlugin from '@optimystic/quereus-plugin-optimystic/plugin';
|
|
3
3
|
import { STRAND_SCHEMA } from './strand-schema.js';
|
|
4
|
-
import { resolveStrandClusterSize } from './cluster-size.js';
|
|
5
|
-
import { wrapStorageWithCache } from './cached-storage.js';
|
|
4
|
+
import { resolveStrandClusterSize, STRAND_CLUSTER_POLICY } from './cluster-size.js';
|
|
5
|
+
import { wrapStorageWithCache, disposeStorageCache } from './cached-storage.js';
|
|
6
6
|
const log = debug('sereus:plugin:strand');
|
|
7
7
|
const timing = debug('sereus:plugin:strand:timing');
|
|
8
8
|
/**
|
|
@@ -49,32 +49,52 @@ export async function composeStrand(db, options, platform) {
|
|
|
49
49
|
// transactor's `rawStorageFactory` and node creation, so it must be decided
|
|
50
50
|
// up front (before pluginConfig is built). Wrapped in the write-through
|
|
51
51
|
// raw-storage cache (cached-storage.ts) — idempotent, so a caller that
|
|
52
|
-
// already wrapped (cadre-core's seams) passes through unchanged
|
|
52
|
+
// already wrapped (cadre-core's seams) passes through unchanged, with this
|
|
53
|
+
// composition counted as one more holder of that same cache.
|
|
53
54
|
const resolvedStorage = platform.resolveStorage
|
|
54
55
|
? await platform.resolveStorage({ strandId, resolvedTransactor, requestedStorage: options.storage })
|
|
55
56
|
: options.storage;
|
|
56
57
|
const storage = resolvedStorage ? wrapStorageWithCache(resolvedStorage, strandId) : resolvedStorage;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Release THIS composition's claim on the storage cache — the matching half of the
|
|
60
|
+
* wrap above, which took one. `wrapStorageWithCache` counts holders, so this is
|
|
61
|
+
* unconditionally correct whoever created the wrapper: the cache stays live while
|
|
62
|
+
* cadre-core (or any other seam over the same store) still holds a claim, and is
|
|
63
|
+
* emptied and unregistered from the shared cache pool when the last one goes. Holding
|
|
64
|
+
* a claim past the strand's life is not free — the registration claims the backing
|
|
65
|
+
* store in the pool, and a claim outliving its strand makes the next connect over that
|
|
66
|
+
* same directory throw.
|
|
67
|
+
*
|
|
68
|
+
* Latched, so a caller that calls `shutdown()` twice releases one claim, not two — a
|
|
69
|
+
* second release would consume another scope's claim.
|
|
70
|
+
*/
|
|
71
|
+
let storageCacheReleased = false;
|
|
72
|
+
const releaseStorageCache = async () => {
|
|
73
|
+
if (storageCacheReleased || !storage) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
storageCacheReleased = true;
|
|
77
|
+
await disposeStorageCache(storage);
|
|
68
78
|
};
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
// 1-2. Register the crypto and optimystic plugins. Guarded on its own, because the
|
|
80
|
+
// wrap above has ALREADY taken a holder claim: a registration that throws must release
|
|
81
|
+
// it, or the claim — and the backing store's registration in the shared cache pool —
|
|
82
|
+
// outlives the failed connect for the process lifetime, and no other scope can retire
|
|
83
|
+
// the cache. Separate from the larger try below, which has a collection factory and
|
|
84
|
+
// possibly a node to tear down as well; neither exists yet here.
|
|
85
|
+
let pluginResult;
|
|
86
|
+
try {
|
|
87
|
+
pluginResult = await registerStrandPlugins(db, platform, {
|
|
88
|
+
resolvedTransactor,
|
|
89
|
+
networkName,
|
|
90
|
+
enableCache,
|
|
91
|
+
storage,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
await releaseStorageCache();
|
|
96
|
+
throw err;
|
|
71
97
|
}
|
|
72
|
-
// The plugin's published signature is `Record<string, SqlValue>` but it
|
|
73
|
-
// also reads `rawStorageFactory` (a function reference) from the same map.
|
|
74
|
-
// Cast through unknown rather than widen the public type.
|
|
75
|
-
const pluginResult = optimysticPlugin(db, pluginConfig);
|
|
76
|
-
applyRegistrations(db, pluginResult);
|
|
77
|
-
log('Registered optimystic vtables and functions');
|
|
78
98
|
const { collectionFactory } = pluginResult;
|
|
79
99
|
let createdNode = null;
|
|
80
100
|
let hydrated;
|
|
@@ -93,7 +113,7 @@ export async function composeStrand(db, options, platform) {
|
|
|
93
113
|
log('Using injected libp2p node');
|
|
94
114
|
}
|
|
95
115
|
else {
|
|
96
|
-
const created = await platform.createNode({ networkName, bootstrapNodes, fretProfile, port, clusterSize, storage });
|
|
116
|
+
const created = await platform.createNode({ networkName, bootstrapNodes, fretProfile, port, clusterSize, clusterPolicy: STRAND_CLUSTER_POLICY, storage });
|
|
97
117
|
createdNode = created;
|
|
98
118
|
node = created;
|
|
99
119
|
const repo = created.coordinatedRepo;
|
|
@@ -136,11 +156,11 @@ export async function composeStrand(db, options, platform) {
|
|
|
136
156
|
// Manager/Member, invite/peer flows) is owned by the lifecycle ticket
|
|
137
157
|
// `strand-membership-lifecycle-population`.
|
|
138
158
|
log('Applying Strand membership schema for strand %s', strandId);
|
|
139
|
-
await db.exec(`
|
|
140
|
-
declare schema Strand {
|
|
141
|
-
${STRAND_SCHEMA}
|
|
142
|
-
}
|
|
143
|
-
apply schema Strand;
|
|
159
|
+
await db.exec(`
|
|
160
|
+
declare schema Strand {
|
|
161
|
+
${STRAND_SCHEMA}
|
|
162
|
+
}
|
|
163
|
+
apply schema Strand;
|
|
144
164
|
`);
|
|
145
165
|
log('Strand membership schema applied');
|
|
146
166
|
// 7. Apply the sApp schema, if provided.
|
|
@@ -150,11 +170,11 @@ export async function composeStrand(db, options, platform) {
|
|
|
150
170
|
// here so it stays a one-location edit across Node, browser, and cadre-core.
|
|
151
171
|
if (schema) {
|
|
152
172
|
log('Applying sApp schema for strand %s', strandId);
|
|
153
|
-
await db.exec(`
|
|
154
|
-
declare schema App {
|
|
155
|
-
${schema}
|
|
156
|
-
}
|
|
157
|
-
apply schema App;
|
|
173
|
+
await db.exec(`
|
|
174
|
+
declare schema App {
|
|
175
|
+
${schema}
|
|
176
|
+
}
|
|
177
|
+
apply schema App;
|
|
158
178
|
`);
|
|
159
179
|
log('sApp schema applied');
|
|
160
180
|
}
|
|
@@ -165,6 +185,7 @@ export async function composeStrand(db, options, platform) {
|
|
|
165
185
|
if (createdNode) {
|
|
166
186
|
await createdNode.stop();
|
|
167
187
|
}
|
|
188
|
+
await releaseStorageCache();
|
|
168
189
|
throw err;
|
|
169
190
|
}
|
|
170
191
|
// 8. Return result with hydrate counts + shutdown handler. `shutdown` tears
|
|
@@ -187,8 +208,37 @@ export async function composeStrand(db, options, platform) {
|
|
|
187
208
|
if (createdNode) {
|
|
188
209
|
await createdNode.stop();
|
|
189
210
|
}
|
|
211
|
+
await releaseStorageCache();
|
|
190
212
|
log('Strand connection %s shut down', strandId);
|
|
191
213
|
},
|
|
192
214
|
};
|
|
193
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Steps 1-2 of {@link composeStrand}: register the crypto plugin, then the optimystic
|
|
218
|
+
* plugin carrying this strand's transactor defaults. Split out so the composition can
|
|
219
|
+
* guard the pair against the storage-cache claim it has already taken.
|
|
220
|
+
*/
|
|
221
|
+
async function registerStrandPlugins(db, platform, strand) {
|
|
222
|
+
await platform.registerCrypto(db);
|
|
223
|
+
log('Registered crypto plugin');
|
|
224
|
+
// On the local transactor with persistent storage, hand the same instance to the
|
|
225
|
+
// plugin so DML persists on the host backend (not in-memory).
|
|
226
|
+
const pluginConfig = {
|
|
227
|
+
default_transactor: strand.resolvedTransactor,
|
|
228
|
+
default_key_network: 'libp2p',
|
|
229
|
+
default_network_name: strand.networkName,
|
|
230
|
+
enable_cache: strand.enableCache,
|
|
231
|
+
};
|
|
232
|
+
if (strand.resolvedTransactor === 'local' && strand.storage) {
|
|
233
|
+
const storage = strand.storage;
|
|
234
|
+
pluginConfig.rawStorageFactory = () => storage;
|
|
235
|
+
}
|
|
236
|
+
// The plugin's published signature is `Record<string, SqlValue>` but it also reads
|
|
237
|
+
// `rawStorageFactory` (a function reference) from the same map. Cast through unknown
|
|
238
|
+
// rather than widen the public type.
|
|
239
|
+
const pluginResult = optimysticPlugin(db, pluginConfig);
|
|
240
|
+
applyRegistrations(db, pluginResult);
|
|
241
|
+
log('Registered optimystic vtables and functions');
|
|
242
|
+
return pluginResult;
|
|
243
|
+
}
|
|
194
244
|
//# sourceMappingURL=compose-strand.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose-strand.js","sourceRoot":"","sources":["../src/compose-strand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,gBAAgB,MAAM,8CAA8C,CAAC;AAK5E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"compose-strand.js","sourceRoot":"","sources":["../src/compose-strand.ts"],"names":[],"mappings":"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"}
|
package/dist/connect-browser.js
CHANGED
|
@@ -30,7 +30,7 @@ export async function connectToStrandBrowser(db, options) {
|
|
|
30
30
|
const dbHandle = await openOptimysticWebDb(`sereus-strand-${strandId}`);
|
|
31
31
|
return new IndexedDBRawStorage(dbHandle);
|
|
32
32
|
},
|
|
33
|
-
async createNode({ networkName, bootstrapNodes, fretProfile, clusterSize, storage }) {
|
|
33
|
+
async createNode({ networkName, bootstrapNodes, fretProfile, clusterSize, clusterPolicy, storage }) {
|
|
34
34
|
return createLibp2pNode({
|
|
35
35
|
transports: [webSockets(), circuitRelayTransport()],
|
|
36
36
|
listenAddrs: [],
|
|
@@ -38,6 +38,7 @@ export async function connectToStrandBrowser(db, options) {
|
|
|
38
38
|
networkName,
|
|
39
39
|
fretProfile,
|
|
40
40
|
clusterSize,
|
|
41
|
+
clusterPolicy,
|
|
41
42
|
...(storage && { storage }),
|
|
42
43
|
});
|
|
43
44
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect-browser.js","sourceRoot":"","sources":["../src/connect-browser.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,0CAA0C,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAG1F,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AASxE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC3C,EAAY,EACZ,OAAgC;IAEhC,OAAO,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE;QACjC,cAAc,CAAC,QAAQ;YACtB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAkC,CAAC,CAAC;QAC3F,CAAC;QACD,KAAK,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,gBAAgB,EAAE;YACtE,IAAI,gBAAgB;gBAAE,OAAO,gBAAgB,CAAC;YAC9C,iEAAiE;YACjE,8CAA8C;YAC9C,IAAI,kBAAkB,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAC;YACpD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;YACxE,OAAO,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE;
|
|
1
|
+
{"version":3,"file":"connect-browser.js","sourceRoot":"","sources":["../src/connect-browser.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,0CAA0C,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAG1F,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AASxE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC3C,EAAY,EACZ,OAAgC;IAEhC,OAAO,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE;QACjC,cAAc,CAAC,QAAQ;YACtB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAkC,CAAC,CAAC;QAC3F,CAAC;QACD,KAAK,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,gBAAgB,EAAE;YACtE,IAAI,gBAAgB;gBAAE,OAAO,gBAAgB,CAAC;YAC9C,iEAAiE;YACjE,8CAA8C;YAC9C,IAAI,kBAAkB,KAAK,MAAM;gBAAE,OAAO,SAAS,CAAC;YACpD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;YACxE,OAAO,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE;YACjG,OAAO,gBAAgB,CAAC;gBACvB,UAAU,EAAE,CAAC,UAAU,EAAE,EAAE,qBAAqB,EAAE,CAAC;gBACnD,WAAW,EAAE,EAAE;gBACf,cAAc;gBACd,WAAW;gBACX,WAAW;gBACX,WAAW;gBACX,aAAa;gBACb,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;aAC3B,CAAoB,CAAC;QACvB,CAAC;KACD,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/connect.js
CHANGED
|
@@ -13,7 +13,7 @@ export async function connectToStrand(db, options) {
|
|
|
13
13
|
async registerCrypto(database) {
|
|
14
14
|
await registerPlugin(database, cryptoPlugin);
|
|
15
15
|
},
|
|
16
|
-
async createNode({ networkName, bootstrapNodes, fretProfile, port, clusterSize, storage }) {
|
|
16
|
+
async createNode({ networkName, bootstrapNodes, fretProfile, port, clusterSize, clusterPolicy, storage }) {
|
|
17
17
|
// Dynamically import to keep the module cross-platform friendly: this
|
|
18
18
|
// pulls the Node-only `@optimystic/db-p2p` (TCP) entry, and is only
|
|
19
19
|
// reached when actually creating a node (never for injected nodes).
|
|
@@ -24,6 +24,7 @@ export async function connectToStrand(db, options) {
|
|
|
24
24
|
networkName,
|
|
25
25
|
fretProfile,
|
|
26
26
|
clusterSize,
|
|
27
|
+
clusterPolicy,
|
|
27
28
|
...(storage && { storage }),
|
|
28
29
|
});
|
|
29
30
|
},
|
package/dist/connect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,YAAY,MAAM,0CAA0C,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACpC,EAAY,EACZ,OAAgC;IAEhC,OAAO,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE;QACjC,KAAK,CAAC,cAAc,CAAC,QAAQ;YAC5B,MAAM,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC9C,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE;
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,YAAY,MAAM,0CAA0C,CAAC;AAGpE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACpC,EAAY,EACZ,OAAgC;IAEhC,OAAO,aAAa,CAAC,EAAE,EAAE,OAAO,EAAE;QACjC,KAAK,CAAC,cAAc,CAAC,QAAQ;YAC5B,MAAM,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC9C,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE;YACvG,sEAAsE;YACtE,oEAAoE;YACpE,oEAAoE;YACpE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAChE,OAAO,gBAAgB,CAAC;gBACvB,IAAI;gBACJ,cAAc;gBACd,WAAW;gBACX,WAAW;gBACX,WAAW;gBACX,aAAa;gBACb,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;aAC3B,CAAoB,CAAC;QACvB,CAAC;KACD,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { connectToStrand } from './connect.js';
|
|
2
|
-
export { MIN_CLUSTER_SIZE, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize } from './cluster-size.js';
|
|
2
|
+
export { MIN_CLUSTER_SIZE, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize, resolveRepairYardstick, controlClusterPolicy, strandClusterPolicy } from './cluster-size.js';
|
|
3
3
|
export { wrapStorageWithCache, disposeStorageCache } from './cached-storage.js';
|
|
4
4
|
export type { StrandConnectionOptions, SereusPluginResult, StrandTransactor } from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { connectToStrand } from './connect.js';
|
|
2
|
-
export { MIN_CLUSTER_SIZE, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize } from './cluster-size.js';
|
|
2
|
+
export { MIN_CLUSTER_SIZE, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize, resolveRepairYardstick, controlClusterPolicy, strandClusterPolicy } from './cluster-size.js';
|
|
3
3
|
export { wrapStorageWithCache, disposeStorageCache } from './cached-storage.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACN,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,EACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACN,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|