@kanzo-tech/graph 0.13.1 → 0.15.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 +12 -15
- package/dist/core/categories.d.ts +18 -6
- package/dist/core/categories.d.ts.map +1 -1
- package/dist/core/categories.js +41 -10
- package/dist/core/categories.js.map +1 -1
- package/dist/core/channels.d.ts +10 -5
- package/dist/core/channels.d.ts.map +1 -1
- package/dist/core/channels.js +11 -13
- package/dist/core/channels.js.map +1 -1
- package/dist/core/detail.d.ts +14 -8
- package/dist/core/detail.d.ts.map +1 -1
- package/dist/core/detail.js +33 -15
- package/dist/core/detail.js.map +1 -1
- package/dist/core/filter.d.ts +3 -1
- package/dist/core/filter.d.ts.map +1 -1
- package/dist/core/filter.js +54 -50
- package/dist/core/filter.js.map +1 -1
- package/dist/core/load.d.ts +58 -0
- package/dist/core/load.d.ts.map +1 -0
- package/dist/core/load.js +115 -0
- package/dist/core/load.js.map +1 -0
- package/dist/core/state.d.ts +31 -56
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/store.d.ts +1 -3
- package/dist/core/store.d.ts.map +1 -1
- package/dist/core/store.js +162 -172
- package/dist/core/store.js.map +1 -1
- package/dist/core/types.d.ts +21 -17
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -25
- package/dist/index.js.map +1 -1
- package/dist/parts/gesture.d.ts +1 -10
- package/dist/parts/gesture.d.ts.map +1 -1
- package/dist/parts/gesture.js +26 -28
- package/dist/parts/gesture.js.map +1 -1
- package/dist/parts/graph-canvas.d.ts.map +1 -1
- package/dist/parts/graph-canvas.js +128 -106
- package/dist/parts/graph-canvas.js.map +1 -1
- package/dist/parts/graph-inspector.d.ts +4 -4
- package/dist/parts/graph-inspector.d.ts.map +1 -1
- package/dist/parts/graph-inspector.js +55 -57
- package/dist/parts/graph-inspector.js.map +1 -1
- package/dist/parts/graph-legend.d.ts +4 -4
- package/dist/parts/graph-legend.d.ts.map +1 -1
- package/dist/parts/graph-legend.js +21 -21
- package/dist/parts/graph-legend.js.map +1 -1
- package/dist/parts/graph-toolbar.d.ts +1 -1
- package/dist/parts/graph-toolbar.d.ts.map +1 -1
- package/dist/parts/graph-toolbar.js +40 -40
- package/dist/parts/graph-toolbar.js.map +1 -1
- package/dist/parts/overlays.d.ts +6 -5
- package/dist/parts/overlays.d.ts.map +1 -1
- package/dist/parts/overlays.js +70 -68
- package/dist/parts/overlays.js.map +1 -1
- package/dist/react/use-graph-state.d.ts +4 -2
- package/dist/react/use-graph-state.d.ts.map +1 -1
- package/dist/react/use-graph-state.js +10 -6
- package/dist/react/use-graph-state.js.map +1 -1
- package/dist/react/use-graph.d.ts +1 -4
- package/dist/react/use-graph.d.ts.map +1 -1
- package/dist/react/use-graph.js +38 -49
- package/dist/react/use-graph.js.map +1 -1
- package/dist/render/graph-looks.d.ts.map +1 -1
- package/dist/render/graph-looks.js.map +1 -1
- package/dist/render/graph-model.d.ts +6 -8
- package/dist/render/graph-model.d.ts.map +1 -1
- package/dist/render/graph-model.js +51 -57
- package/dist/render/graph-model.js.map +1 -1
- package/dist/render/graph-sim.d.ts +2 -3
- package/dist/render/graph-sim.d.ts.map +1 -1
- package/dist/render/graph-sim.js.map +1 -1
- package/dist/render/renderer.d.ts +10 -10
- package/dist/render/renderer.d.ts.map +1 -1
- package/dist/render/renderer.js +121 -177
- package/dist/render/renderer.js.map +1 -1
- package/dist/section.d.ts.map +1 -1
- package/dist/section.js +3 -7
- package/dist/section.js.map +1 -1
- package/package.json +29 -10
- package/dist/core/refine.d.ts +0 -14
- package/dist/core/refine.d.ts.map +0 -1
- package/dist/core/refine.js +0 -20
- package/dist/core/refine.js.map +0 -1
- package/dist/core/resident.d.ts +0 -79
- package/dist/core/resident.d.ts.map +0 -1
- package/dist/core/resident.js +0 -44
- package/dist/core/resident.js.map +0 -1
- package/dist/core/scheduler.d.ts +0 -42
- package/dist/core/scheduler.d.ts.map +0 -1
- package/dist/core/scheduler.js +0 -77
- package/dist/core/scheduler.js.map +0 -1
- package/dist/core/tile-matrix.d.ts +0 -37
- package/dist/core/tile-matrix.d.ts.map +0 -1
- package/dist/core/tile-matrix.js +0 -49
- package/dist/core/tile-matrix.js.map +0 -1
- package/dist/core/tile.d.ts +0 -54
- package/dist/core/tile.d.ts.map +0 -1
- package/dist/core/tile.js +0 -76
- package/dist/core/tile.js.map +0 -1
- package/dist/core/tileset.d.ts +0 -59
- package/dist/core/tileset.d.ts.map +0 -1
- package/dist/core/tileset.js +0 -177
- package/dist/core/tileset.js.map +0 -1
- package/dist/render/adaptive.d.ts +0 -27
- package/dist/render/adaptive.d.ts.map +0 -1
- package/dist/render/adaptive.js +0 -25
- package/dist/render/adaptive.js.map +0 -1
- package/dist/render/compose.d.ts +0 -51
- package/dist/render/compose.d.ts.map +0 -1
- package/dist/render/compose.js +0 -107
- package/dist/render/compose.js.map +0 -1
- package/dist/render/encode.d.ts +0 -42
- package/dist/render/encode.d.ts.map +0 -1
- package/dist/render/encode.js +0 -68
- package/dist/render/encode.js.map +0 -1
- package/dist/render/when-ready.d.ts +0 -35
- package/dist/render/when-ready.d.ts.map +0 -1
- package/dist/render/when-ready.js +0 -17
- package/dist/render/when-ready.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanzo-tech/graph",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Kanzo graph view — a
|
|
3
|
+
"version": "0.15.0",
|
|
4
|
+
"description": "Kanzo graph view — a whole fossil corpus, read once through its scan and drawn with cosmos.gl, inside the page's Mosaic crossfilter. Sibling of @kanzo-tech/ui, not part of it: the admission rules exclude graphs from the generic vocabulary by name.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
},
|
|
23
23
|
"./package.json": "./package.json"
|
|
24
24
|
},
|
|
25
|
-
"//peers": "All required. cosmos.gl draws; `lucide-react` is the icon set the parts draw their buttons with, `@kanzo-tech/ui`'s own peer; `@fossil-lang/corpus` is the backend — the host opens a corpus with its `open` on `@kanzo-tech/mosaic`'s `engine()` and this package draws it through
|
|
26
|
-
"//fossil": "The
|
|
25
|
+
"//peers": "All required. cosmos.gl draws; `lucide-react` is the icon set the parts draw their buttons with, `@kanzo-tech/ui`'s own peer; `@fossil-lang/corpus` is the backend — the host opens a corpus with its `open` on `@kanzo-tech/mosaic`'s `engine()` and this package draws it through its `manifest` and `scan`, writing no SQL of its own; `@kanzo-tech/mosaic` carries the crossfilter the graph listens to and publishes into. They were optional while a root barrel with no source and a `./duckdb` entry with one existed side by side; there is one path now and nothing on it is optional (`/docs/design/graph`, *the one host path*). The Mosaic stack itself — mosaic-core, mosaic-sql — is `@kanzo-tech/mosaic`'s peer, declared once there.",
|
|
26
|
+
"//fossil": "The code reads `fossil/1` — `manifest`, `scan({ table })`, a global dense `dense_id` — which `0.3.0-alpha.15` is the first to publish, so it is the floor. Only types are imported; `src/layers.test.ts` holds that.",
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@cosmos.gl/graph": "^3.4.0",
|
|
29
|
-
"@fossil-lang/corpus": "^0.3.0-alpha.
|
|
29
|
+
"@fossil-lang/corpus": "^0.3.0-alpha.15",
|
|
30
30
|
"lucide-react": ">=1",
|
|
31
31
|
"react": "^19.0.0",
|
|
32
|
-
"@kanzo-tech/mosaic": "0.
|
|
33
|
-
"@kanzo-tech/ui": "0.
|
|
32
|
+
"@kanzo-tech/mosaic": "0.15.0",
|
|
33
|
+
"@kanzo-tech/ui": "0.15.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@cosmos.gl/graph": "^3.4.0",
|
|
37
|
-
"@fossil-lang/corpus": "^0.3.0-alpha.
|
|
37
|
+
"@fossil-lang/corpus": "^0.3.0-alpha.15",
|
|
38
38
|
"@testing-library/dom": "^10.4.1",
|
|
39
39
|
"@testing-library/react": "^16.3.2",
|
|
40
40
|
"@types/react": "^19.0.0",
|
|
@@ -46,8 +46,26 @@
|
|
|
46
46
|
"react": "^19.0.0",
|
|
47
47
|
"react-dom": "^19.0.0",
|
|
48
48
|
"rollup-plugin-preserve-directives": "^0.4.0",
|
|
49
|
-
"@kanzo-tech/mosaic": "0.
|
|
49
|
+
"@kanzo-tech/mosaic": "0.15.0"
|
|
50
50
|
},
|
|
51
|
+
"//size-limit": "Budgets our code only: `ignore` mirrors the peers the build externalises in vite.config.ts, cosmos.gl included (about 190 kB gzipped on its own, and the consumer pays it once whatever this package does). First measured 2026-09-30 at 19.07 kB, before the lag work of `perf/phase1-lag`; 19.13 kB before the whole-corpus store deleted the tileset, 15.29 kB after it, and the budget follows it down so real growth trips the gate.",
|
|
52
|
+
"size-limit": [
|
|
53
|
+
{
|
|
54
|
+
"name": "root barrel (JS)",
|
|
55
|
+
"path": "dist/index.js",
|
|
56
|
+
"limit": "15.5 kB",
|
|
57
|
+
"ignore": [
|
|
58
|
+
"react",
|
|
59
|
+
"react-dom",
|
|
60
|
+
"react/jsx-runtime",
|
|
61
|
+
"@cosmos.gl/graph",
|
|
62
|
+
"@fossil-lang/corpus",
|
|
63
|
+
"@kanzo-tech/mosaic",
|
|
64
|
+
"@kanzo-tech/ui",
|
|
65
|
+
"lucide-react"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
],
|
|
51
69
|
"repository": {
|
|
52
70
|
"type": "git",
|
|
53
71
|
"url": "git+https://github.com/Kanzo-Tech/ui.git",
|
|
@@ -60,6 +78,7 @@
|
|
|
60
78
|
"scripts": {
|
|
61
79
|
"build": "vite build",
|
|
62
80
|
"typecheck": "tsc --noEmit",
|
|
63
|
-
"test": "vitest run"
|
|
81
|
+
"test": "vitest run",
|
|
82
|
+
"size": "size-limit"
|
|
64
83
|
}
|
|
65
84
|
}
|
package/dist/core/refine.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Tile } from './tile';
|
|
2
|
-
/**
|
|
3
|
-
* deck.gl's `'best-available'` refinement — `updateTileStateDefault`, the only strategy.
|
|
4
|
-
*
|
|
5
|
-
* A selected tile with content is drawn. One without is covered by its nearest ancestor holding
|
|
6
|
-
* content, and failing that by whatever of its descendants holds some, so a pan never shows a hole.
|
|
7
|
-
* A parent is therefore drawn only while a selected child is loading: at rest every selected tile
|
|
8
|
-
* holds content and no stand-in is needed.
|
|
9
|
-
*
|
|
10
|
-
* "Holding content" rather than deck.gl's `isLoaded`, because a tile reloading for a new question
|
|
11
|
-
* keeps its old picture until the new one arrives.
|
|
12
|
-
*/
|
|
13
|
-
export declare function refine(tiles: Iterable<Tile>): void;
|
|
14
|
-
//# sourceMappingURL=refine.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"refine.d.ts","sourceRoot":"","sources":["../../src/core/refine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAOlD"}
|
package/dist/core/refine.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
function f(o) {
|
|
2
|
-
const n = [...o], e = /* @__PURE__ */ new Set();
|
|
3
|
-
for (const t of n)
|
|
4
|
-
t.isSelected && !c(t, e) && i(t, e);
|
|
5
|
-
for (const t of n) t.isVisible = e.has(t);
|
|
6
|
-
}
|
|
7
|
-
function c(o, n) {
|
|
8
|
-
for (let e = o; e; e = e.parent)
|
|
9
|
-
if (e.content)
|
|
10
|
-
return n.add(e), !0;
|
|
11
|
-
return !1;
|
|
12
|
-
}
|
|
13
|
-
function i(o, n) {
|
|
14
|
-
for (const e of o.children)
|
|
15
|
-
e.content ? n.add(e) : i(e, n);
|
|
16
|
-
}
|
|
17
|
-
export {
|
|
18
|
-
f as refine
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=refine.js.map
|
package/dist/core/refine.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"refine.js","sources":["../../src/core/refine.ts"],"sourcesContent":["import type { Tile } from \"./tile\";\n\n/**\n * deck.gl's `'best-available'` refinement — `updateTileStateDefault`, the only strategy.\n *\n * A selected tile with content is drawn. One without is covered by its nearest ancestor holding\n * content, and failing that by whatever of its descendants holds some, so a pan never shows a hole.\n * A parent is therefore drawn only while a selected child is loading: at rest every selected tile\n * holds content and no stand-in is needed.\n *\n * \"Holding content\" rather than deck.gl's `isLoaded`, because a tile reloading for a new question\n * keeps its old picture until the new one arrives.\n */\nexport function refine(tiles: Iterable<Tile>): void {\n const all = [...tiles];\n const visible = new Set<Tile>();\n for (const tile of all) {\n if (tile.isSelected && !inAncestors(tile, visible)) inDescendants(tile, visible);\n }\n for (const tile of all) tile.isVisible = visible.has(tile);\n}\n\nfunction inAncestors(start: Tile, visible: Set<Tile>): boolean {\n for (let tile: Tile | null = start; tile; tile = tile.parent) {\n if (tile.content) {\n visible.add(tile);\n return true;\n }\n }\n return false;\n}\n\nfunction inDescendants(tile: Tile, visible: Set<Tile>): void {\n for (const child of tile.children) {\n if (child.content) visible.add(child);\n else inDescendants(child, visible);\n }\n}\n"],"names":["refine","tiles","all","visible","tile","inAncestors","inDescendants","start","child"],"mappings":"AAaO,SAASA,EAAOC,GAA6B;AAClD,QAAMC,IAAM,CAAC,GAAGD,CAAK,GACfE,wBAAc,IAAA;AACpB,aAAWC,KAAQF;AACjB,IAAIE,EAAK,cAAc,CAACC,EAAYD,GAAMD,CAAO,KAAGG,EAAcF,GAAMD,CAAO;AAEjF,aAAWC,KAAQF,EAAK,CAAAE,EAAK,YAAYD,EAAQ,IAAIC,CAAI;AAC3D;AAEA,SAASC,EAAYE,GAAaJ,GAA6B;AAC7D,WAASC,IAAoBG,GAAOH,GAAMA,IAAOA,EAAK;AACpD,QAAIA,EAAK;AACP,aAAAD,EAAQ,IAAIC,CAAI,GACT;AAGX,SAAO;AACT;AAEA,SAASE,EAAcF,GAAYD,GAA0B;AAC3D,aAAWK,KAASJ,EAAK;AACvB,IAAII,EAAM,UAASL,EAAQ,IAAIK,CAAK,IAC/BF,EAAcE,GAAOL,CAAO;AAErC;"}
|
package/dist/core/resident.d.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Who is drawn, and where the GPU is drawing them.
|
|
3
|
-
*
|
|
4
|
-
* **A buffer index numbers the answer, not the corpus.** cosmos.gl addresses every point by its
|
|
5
|
-
* position in the arrays it was last handed, so index 7 is whatever the current answer put seventh —
|
|
6
|
-
* and a resident set that comes and goes reuses every index while the vertices behind them change.
|
|
7
|
-
* Anything that outlives one answer — a selection, a label, a hover, a pin — therefore has to be
|
|
8
|
-
* held as an identity and re-resolved against whatever is drawn now.
|
|
9
|
-
*
|
|
10
|
-
* **A vertex is the pair `(type_idx, dense_id)`.** Not `dense_id` alone: it numbers
|
|
11
|
-
* within one vertex type, so a union of two types repeats every value and the same number names two
|
|
12
|
-
* different vertices. A `LIMIT` breaks the correspondence between an id and a position regardless of
|
|
13
|
-
* how many types there are.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* A vertex identity — the pair, packed into one 64-bit integer so it can key a `Map` and a `Set`.
|
|
17
|
-
*
|
|
18
|
-
* **A `bigint`, which is strictly stronger than the brand it also wears.** A buffer index is a
|
|
19
|
-
* `number`; an identity is a `bigint`. Confusing the two therefore stops being a branding
|
|
20
|
-
* convention that holds while everyone remembers it and becomes a *primitive* type error — and no
|
|
21
|
-
* cast quietly launders one: `7 as VertexId` was legal against `number & brand` and is a compile
|
|
22
|
-
* error against `bigint & brand`. Getting one wrong now costs `as unknown as`, which is loud.
|
|
23
|
-
*
|
|
24
|
-
* **The evidence this is worth the friction, because it is not a precaution we invented.** Across
|
|
25
|
-
* every multi-language format surveyed — Arrow, Parquet, Iceberg, Delta, MVT, PMTiles, Zarr,
|
|
26
|
-
* GraphAr, H3, S2 — the failure that recurs is a 64-bit value crossing into JavaScript.
|
|
27
|
-
* `mapbox/node-s2` is a **binding**, not a port: it calls the same C++ the reference implementation
|
|
28
|
-
* does, and it still returned wrong cell ids — issue #92, open since 2017, `1152921504606847000`
|
|
29
|
-
* where Java and Go both give `1152921504606846977`. JavaScript's `number` is 53 bits and a cell id
|
|
30
|
-
* is 64, and a binding cannot protect a language boundary that cannot hold the value. H3 settled it
|
|
31
|
-
* by decree before anyone could get it wrong: `h3-js` types `H3Index` as a string. This is the same
|
|
32
|
-
* decree with the type JavaScript grew for it.
|
|
33
|
-
*
|
|
34
|
-
* **And `>>` means three different things across our three layers.** In JavaScript it converts its
|
|
35
|
-
* operand to *32 bits* and takes the shift count modulo 32, so the obvious `dense | (type << 32)`
|
|
36
|
-
* is not a lost high word — it is `type | dense`, silently. The packing below cannot be written on
|
|
37
|
-
* `number` at all and be right.
|
|
38
|
-
*
|
|
39
|
-
* What goes to the GPU does not change: positions and buffer indices stay `number` and
|
|
40
|
-
* `Float32Array`. The conversion happens at the edge, which is where it belongs.
|
|
41
|
-
*/
|
|
42
|
-
export type VertexId = bigint & {
|
|
43
|
-
readonly vertex: unique symbol;
|
|
44
|
-
};
|
|
45
|
-
export declare function vertexId(type: number, dense: number): VertexId;
|
|
46
|
-
/** Both halves come back as `number`: each is 32 bits, and a `number` holds those exactly. */
|
|
47
|
-
export declare function typeOf(vertex: VertexId): number;
|
|
48
|
-
export declare function denseOf(vertex: VertexId): number;
|
|
49
|
-
/**
|
|
50
|
-
* The identity↔index map for whatever is drawn right now.
|
|
51
|
-
*
|
|
52
|
-
* Built once per residency change and never mutated, because that is what a residency change *is*: a
|
|
53
|
-
* different set of vertices, in a different order. It belongs to whoever owns residency — that is
|
|
54
|
-
* the renderer, which composes the buffers — and is read from there by everything else, because a
|
|
55
|
-
* second copy is a second copy that can disagree with the buffers on screen.
|
|
56
|
-
*/
|
|
57
|
-
export interface Resident {
|
|
58
|
-
/** How many points are drawn. */
|
|
59
|
-
readonly size: number;
|
|
60
|
-
/** Where a vertex is drawn, or `undefined` when it is not resident. */
|
|
61
|
-
indexOf(vertex: VertexId): number | undefined;
|
|
62
|
-
/** Which vertex is drawn at a buffer index, or `undefined` past the end of the answer. */
|
|
63
|
-
at(index: number): VertexId | undefined;
|
|
64
|
-
/** Where these vertices are drawn, skipping every one that is not resident. */
|
|
65
|
-
indicesOf(vertices: Iterable<VertexId>): number[];
|
|
66
|
-
/** Which vertices are drawn at these buffer indices, skipping any the answer does not hold. */
|
|
67
|
-
verticesAt(indices: Iterable<number>): VertexId[];
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* The map a composition implies, over its first `size` slots. A composition puts its vertices
|
|
71
|
-
* first — then the cells, which have no identity, then the far ends drawn only so an edge has one —
|
|
72
|
-
* so nothing hovers, selects or frames a slot past them. Before the first composition nobody is
|
|
73
|
-
* resident, which is not an error.
|
|
74
|
-
*
|
|
75
|
-
* Keyed by the identity itself. `Map` and `Set` compare keys by SameValueZero, which for a `bigint`
|
|
76
|
-
* is *value* equality — asserted in `resident.test.ts`, because the whole file rests on it.
|
|
77
|
-
*/
|
|
78
|
-
export declare function residentOf(vertices?: BigUint64Array | null, size?: number): Resident;
|
|
79
|
-
//# sourceMappingURL=resident.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resident.d.ts","sourceRoot":"","sources":["../../src/core/resident.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,MAAM,CAAA;CAAE,CAAC;AAYnE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,CAE9D;AAED,8FAA8F;AAC9F,wBAAgB,MAAM,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAE/C;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAEhD;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IAC9C,0FAA0F;IAC1F,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IACxC,+EAA+E;IAC/E,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE,CAAC;IAClD,+FAA+F;IAC/F,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;CACnD;AAID;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,QAAQ,GAAE,cAAc,GAAG,IAAa,EAAE,IAAI,SAAwB,GAAG,QAAQ,CA6B3G"}
|
package/dist/core/resident.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
const O = 32n, a = 0xffffffffn;
|
|
2
|
-
function g(t, e) {
|
|
3
|
-
return BigInt(t) << O | BigInt(e);
|
|
4
|
-
}
|
|
5
|
-
function h(t) {
|
|
6
|
-
return Number(t >> O);
|
|
7
|
-
}
|
|
8
|
-
function l(t) {
|
|
9
|
-
return Number(t & a);
|
|
10
|
-
}
|
|
11
|
-
const x = new BigUint64Array(0);
|
|
12
|
-
function p(t = x, e = (t == null ? void 0 : t.length) ?? 0) {
|
|
13
|
-
const r = t ?? x, i = Math.min(e, r.length), u = /* @__PURE__ */ new Map();
|
|
14
|
-
for (let n = 0; n < i; n++) u.set(r[n], n);
|
|
15
|
-
const c = (n) => n >= 0 && n < i ? r[n] : void 0, d = (n) => u.get(n);
|
|
16
|
-
return {
|
|
17
|
-
size: i,
|
|
18
|
-
indexOf: d,
|
|
19
|
-
at: c,
|
|
20
|
-
indicesOf(n) {
|
|
21
|
-
const o = [];
|
|
22
|
-
for (const s of n) {
|
|
23
|
-
const f = d(s);
|
|
24
|
-
f !== void 0 && o.push(f);
|
|
25
|
-
}
|
|
26
|
-
return o;
|
|
27
|
-
},
|
|
28
|
-
verticesAt(n) {
|
|
29
|
-
const o = [];
|
|
30
|
-
for (const s of n) {
|
|
31
|
-
const f = c(s);
|
|
32
|
-
f !== void 0 && o.push(f);
|
|
33
|
-
}
|
|
34
|
-
return o;
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
export {
|
|
39
|
-
l as denseOf,
|
|
40
|
-
p as residentOf,
|
|
41
|
-
h as typeOf,
|
|
42
|
-
g as vertexId
|
|
43
|
-
};
|
|
44
|
-
//# sourceMappingURL=resident.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resident.js","sources":["../../src/core/resident.ts"],"sourcesContent":["\n/**\n * Who is drawn, and where the GPU is drawing them.\n *\n * **A buffer index numbers the answer, not the corpus.** cosmos.gl addresses every point by its\n * position in the arrays it was last handed, so index 7 is whatever the current answer put seventh —\n * and a resident set that comes and goes reuses every index while the vertices behind them change.\n * Anything that outlives one answer — a selection, a label, a hover, a pin — therefore has to be\n * held as an identity and re-resolved against whatever is drawn now.\n *\n * **A vertex is the pair `(type_idx, dense_id)`.** Not `dense_id` alone: it numbers\n * within one vertex type, so a union of two types repeats every value and the same number names two\n * different vertices. A `LIMIT` breaks the correspondence between an id and a position regardless of\n * how many types there are.\n */\n\n/**\n * A vertex identity — the pair, packed into one 64-bit integer so it can key a `Map` and a `Set`.\n *\n * **A `bigint`, which is strictly stronger than the brand it also wears.** A buffer index is a\n * `number`; an identity is a `bigint`. Confusing the two therefore stops being a branding\n * convention that holds while everyone remembers it and becomes a *primitive* type error — and no\n * cast quietly launders one: `7 as VertexId` was legal against `number & brand` and is a compile\n * error against `bigint & brand`. Getting one wrong now costs `as unknown as`, which is loud.\n *\n * **The evidence this is worth the friction, because it is not a precaution we invented.** Across\n * every multi-language format surveyed — Arrow, Parquet, Iceberg, Delta, MVT, PMTiles, Zarr,\n * GraphAr, H3, S2 — the failure that recurs is a 64-bit value crossing into JavaScript.\n * `mapbox/node-s2` is a **binding**, not a port: it calls the same C++ the reference implementation\n * does, and it still returned wrong cell ids — issue #92, open since 2017, `1152921504606847000`\n * where Java and Go both give `1152921504606846977`. JavaScript's `number` is 53 bits and a cell id\n * is 64, and a binding cannot protect a language boundary that cannot hold the value. H3 settled it\n * by decree before anyone could get it wrong: `h3-js` types `H3Index` as a string. This is the same\n * decree with the type JavaScript grew for it.\n *\n * **And `>>` means three different things across our three layers.** In JavaScript it converts its\n * operand to *32 bits* and takes the shift count modulo 32, so the obvious `dense | (type << 32)`\n * is not a lost high word — it is `type | dense`, silently. The packing below cannot be written on\n * `number` at all and be right.\n *\n * What goes to the GPU does not change: positions and buffer indices stay `number` and\n * `Float32Array`. The conversion happens at the edge, which is where it belongs.\n */\nexport type VertexId = bigint & { readonly vertex: unique symbol };\n\n/**\n * One type's worth of dense ids.\n *\n * `dense_id` is a `UInt32`, so the type index occupies everything above bit 32 — exactly, for all\n * 2³² of them, which is the whole point of the width. The old packing was `type * 2**32 + dense` in\n * `float64` and ran out of exactness at type index 2²¹.\n */\nconst TYPE_SHIFT = 32n;\nconst DENSE_MASK = 0xffff_ffffn;\n\nexport function vertexId(type: number, dense: number): VertexId {\n return ((BigInt(type) << TYPE_SHIFT) | BigInt(dense)) as VertexId;\n}\n\n/** Both halves come back as `number`: each is 32 bits, and a `number` holds those exactly. */\nexport function typeOf(vertex: VertexId): number {\n return Number(vertex >> TYPE_SHIFT);\n}\n\nexport function denseOf(vertex: VertexId): number {\n return Number(vertex & DENSE_MASK);\n}\n\n/**\n * The identity↔index map for whatever is drawn right now.\n *\n * Built once per residency change and never mutated, because that is what a residency change *is*: a\n * different set of vertices, in a different order. It belongs to whoever owns residency — that is\n * the renderer, which composes the buffers — and is read from there by everything else, because a\n * second copy is a second copy that can disagree with the buffers on screen.\n */\nexport interface Resident {\n /** How many points are drawn. */\n readonly size: number;\n /** Where a vertex is drawn, or `undefined` when it is not resident. */\n indexOf(vertex: VertexId): number | undefined;\n /** Which vertex is drawn at a buffer index, or `undefined` past the end of the answer. */\n at(index: number): VertexId | undefined;\n /** Where these vertices are drawn, skipping every one that is not resident. */\n indicesOf(vertices: Iterable<VertexId>): number[];\n /** Which vertices are drawn at these buffer indices, skipping any the answer does not hold. */\n verticesAt(indices: Iterable<number>): VertexId[];\n}\n\nconst NOBODY = new BigUint64Array(0);\n\n/**\n * The map a composition implies, over its first `size` slots. A composition puts its vertices\n * first — then the cells, which have no identity, then the far ends drawn only so an edge has one —\n * so nothing hovers, selects or frames a slot past them. Before the first composition nobody is\n * resident, which is not an error.\n *\n * Keyed by the identity itself. `Map` and `Set` compare keys by SameValueZero, which for a `bigint`\n * is *value* equality — asserted in `resident.test.ts`, because the whole file rests on it.\n */\nexport function residentOf(vertices: BigUint64Array | null = NOBODY, size = vertices?.length ?? 0): Resident {\n const all = vertices ?? NOBODY;\n const drawn = Math.min(size, all.length);\n const index = new Map<bigint, number>();\n for (let i = 0; i < drawn; i++) index.set(all[i] as bigint, i);\n const at = (i: number): VertexId | undefined => (i >= 0 && i < drawn ? (all[i] as VertexId) : undefined);\n const indexOf = (vertex: VertexId): number | undefined => index.get(vertex);\n\n return {\n size: drawn,\n indexOf,\n at,\n indicesOf(wanted) {\n const found: number[] = [];\n for (const vertex of wanted) {\n const i = indexOf(vertex);\n if (i !== undefined) found.push(i);\n }\n return found;\n },\n verticesAt(indices) {\n const found: VertexId[] = [];\n for (const i of indices) {\n const vertex = at(i);\n if (vertex !== undefined) found.push(vertex);\n }\n return found;\n },\n };\n}\n"],"names":["TYPE_SHIFT","DENSE_MASK","vertexId","type","dense","typeOf","vertex","denseOf","NOBODY","residentOf","vertices","size","all","drawn","index","i","at","indexOf","wanted","found","indices"],"mappings":"AAoDA,MAAMA,IAAa,KACbC,IAAa;AAEZ,SAASC,EAASC,GAAcC,GAAyB;AAC9D,SAAS,OAAOD,CAAI,KAAKH,IAAc,OAAOI,CAAK;AACrD;AAGO,SAASC,EAAOC,GAA0B;AAC/C,SAAO,OAAOA,KAAUN,CAAU;AACpC;AAEO,SAASO,EAAQD,GAA0B;AAChD,SAAO,OAAOA,IAASL,CAAU;AACnC;AAuBA,MAAMO,IAAS,IAAI,eAAe,CAAC;AAW5B,SAASC,EAAWC,IAAkCF,GAAQG,KAAOD,KAAA,gBAAAA,EAAU,WAAU,GAAa;AAC3G,QAAME,IAAMF,KAAYF,GAClBK,IAAQ,KAAK,IAAIF,GAAMC,EAAI,MAAM,GACjCE,wBAAY,IAAA;AAClB,WAASC,IAAI,GAAGA,IAAIF,GAAOE,OAAW,IAAIH,EAAIG,CAAC,GAAaA,CAAC;AAC7D,QAAMC,IAAK,CAACD,MAAqCA,KAAK,KAAKA,IAAIF,IAASD,EAAIG,CAAC,IAAiB,QACxFE,IAAU,CAACX,MAAyCQ,EAAM,IAAIR,CAAM;AAE1E,SAAO;AAAA,IACL,MAAMO;AAAA,IACN,SAAAI;AAAA,IACA,IAAAD;AAAA,IACA,UAAUE,GAAQ;AAChB,YAAMC,IAAkB,CAAA;AACxB,iBAAWb,KAAUY,GAAQ;AAC3B,cAAMH,IAAIE,EAAQX,CAAM;AACxB,QAAIS,MAAM,UAAWI,EAAM,KAAKJ,CAAC;AAAA,MACnC;AACA,aAAOI;AAAA,IACT;AAAA,IACA,WAAWC,GAAS;AAClB,YAAMD,IAAoB,CAAA;AAC1B,iBAAWJ,KAAKK,GAAS;AACvB,cAAMd,IAASU,EAAGD,CAAC;AACnB,QAAIT,MAAW,UAAWa,EAAM,KAAKb,CAAM;AAAA,MAC7C;AACA,aAAOa;AAAA,IACT;AAAA,EAAA;AAEJ;"}
|
package/dist/core/scheduler.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* loaders.gl's `RequestScheduler`, issuing a **batch** where it issues a request, with one slot:
|
|
3
|
-
* DuckDB-WASM is one worker behind one port, so a second statement queues behind the first rather
|
|
4
|
-
* than overlapping it, and fossil reads a run of consecutive tiles as one statement only when it is
|
|
5
|
-
* handed them in one call (`/docs/design/graph`, *one batch in flight*).
|
|
6
|
-
*
|
|
7
|
-
* Priorities are asked again each time a slot frees, the debounce settles or `prune` runs. A negative
|
|
8
|
-
* priority is a request nobody wants any more: queued, it resolves `null` without ever being issued;
|
|
9
|
-
* in flight, its batch is aborted only once no request in it is wanted — a batch that still answers
|
|
10
|
-
* someone finishes, and answers everyone in it.
|
|
11
|
-
*/
|
|
12
|
-
/** A request's answer, its batch's failure, or `null` when it was never issued or was aborted. */
|
|
13
|
-
export type Outcome<R> = {
|
|
14
|
-
readonly value: R;
|
|
15
|
-
} | {
|
|
16
|
-
readonly error: unknown;
|
|
17
|
-
} | null;
|
|
18
|
-
export interface SchedulerOptions<T, R> {
|
|
19
|
-
/** One call for a batch: an answer per handle, in the order given. */
|
|
20
|
-
run: (handles: readonly T[], signal: AbortSignal) => Promise<readonly R[]>;
|
|
21
|
-
/** Batches running at once. */
|
|
22
|
-
maxRequests?: number;
|
|
23
|
-
/** Quiet time, in milliseconds, before the queue is issued — a pan settles before it asks. */
|
|
24
|
-
debounceTime?: number;
|
|
25
|
-
}
|
|
26
|
-
export declare class RequestScheduler<T, R> {
|
|
27
|
-
#private;
|
|
28
|
-
constructor({ debounceTime, maxRequests, run }: SchedulerOptions<T, R>);
|
|
29
|
-
schedule(handle: T, priority: (handle: T) => number): Promise<Outcome<R>>;
|
|
30
|
-
/** How many requests are queued, and how many batches are running. */
|
|
31
|
-
get size(): {
|
|
32
|
-
queued: number;
|
|
33
|
-
active: number;
|
|
34
|
-
};
|
|
35
|
-
/** The caller no longer wants `handle`'s answer: it resolves `null` now, wherever it is. */
|
|
36
|
-
cancel(handle: T): void;
|
|
37
|
-
/** Drops queued requests nobody wants, and aborts a batch in which nobody wants anything. */
|
|
38
|
-
prune(): void;
|
|
39
|
-
/** Every queued request resolves `null`, and every running batch is aborted. */
|
|
40
|
-
clear(): void;
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/core/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,kGAAkG;AAClG,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI;IAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAAC;AAepF,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,CAAC;IACpC,sEAAsE;IACtE,GAAG,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC3E,+BAA+B;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8FAA8F;IAC9F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,gBAAgB,CAAC,CAAC,EAAE,CAAC;;gBAQpB,EAAE,YAAgB,EAAE,WAAe,EAAE,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC;IAM9E,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAOzE,sEAAsE;IACtE,IAAI,IAAI,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAE7C;IAED,4FAA4F;IAC5F,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI;IAgBvB,6FAA6F;IAC7F,KAAK,IAAI,IAAI;IAYb,gFAAgF;IAChF,KAAK,IAAI,IAAI;CA4Cd"}
|
package/dist/core/scheduler.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
var v = (i) => {
|
|
2
|
-
throw TypeError(i);
|
|
3
|
-
};
|
|
4
|
-
var y = (i, t, e) => t.has(i) || v("Cannot " + e);
|
|
5
|
-
var s = (i, t, e) => (y(i, t, "read from private field"), e ? e.call(i) : t.get(i)), a = (i, t, e) => t.has(i) ? v("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e), n = (i, t, e, r) => (y(i, t, "write to private field"), r ? r.call(i, e) : t.set(i, e), e), p = (i, t, e) => (y(i, t, "access private method"), e);
|
|
6
|
-
var g, w, m, l, o, h, u, q, b, z;
|
|
7
|
-
class x {
|
|
8
|
-
constructor({ debounceTime: t = 0, maxRequests: e = 1, run: r }) {
|
|
9
|
-
a(this, u);
|
|
10
|
-
a(this, g);
|
|
11
|
-
a(this, w);
|
|
12
|
-
a(this, m);
|
|
13
|
-
a(this, l, []);
|
|
14
|
-
a(this, o, /* @__PURE__ */ new Set());
|
|
15
|
-
a(this, h, null);
|
|
16
|
-
n(this, g, r), n(this, w, e), n(this, m, t);
|
|
17
|
-
}
|
|
18
|
-
schedule(t, e) {
|
|
19
|
-
return new Promise((r) => {
|
|
20
|
-
s(this, l).push({ handle: t, priority: e, resolve: r, settled: !1, dropped: !1 }), p(this, u, q).call(this);
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
/** How many requests are queued, and how many batches are running. */
|
|
24
|
-
get size() {
|
|
25
|
-
return { queued: s(this, l).length, active: s(this, o).size };
|
|
26
|
-
}
|
|
27
|
-
/** The caller no longer wants `handle`'s answer: it resolves `null` now, wherever it is. */
|
|
28
|
-
cancel(t) {
|
|
29
|
-
n(this, l, s(this, l).filter((e) => e.handle !== t ? !0 : (f(e, null), !1)));
|
|
30
|
-
for (const e of s(this, o))
|
|
31
|
-
for (const r of e.requests)
|
|
32
|
-
r.handle === t && (r.dropped = !0, f(r, null));
|
|
33
|
-
this.prune();
|
|
34
|
-
}
|
|
35
|
-
/** Drops queued requests nobody wants, and aborts a batch in which nobody wants anything. */
|
|
36
|
-
prune() {
|
|
37
|
-
n(this, l, s(this, l).filter((t) => t.priority(t.handle) >= 0 ? !0 : (f(t, null), !1)));
|
|
38
|
-
for (const t of s(this, o))
|
|
39
|
-
t.requests.some((r) => !r.dropped && r.priority(r.handle) >= 0) || t.controller.abort();
|
|
40
|
-
}
|
|
41
|
-
/** Every queued request resolves `null`, and every running batch is aborted. */
|
|
42
|
-
clear() {
|
|
43
|
-
s(this, h) !== null && clearTimeout(s(this, h)), n(this, h, null);
|
|
44
|
-
for (const t of s(this, l)) f(t, null);
|
|
45
|
-
n(this, l, []);
|
|
46
|
-
for (const t of s(this, o)) t.controller.abort();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
g = new WeakMap(), w = new WeakMap(), m = new WeakMap(), l = new WeakMap(), o = new WeakMap(), h = new WeakMap(), u = new WeakSet(), q = function() {
|
|
50
|
-
s(this, h) !== null && clearTimeout(s(this, h)), n(this, h, setTimeout(() => {
|
|
51
|
-
n(this, h, null), p(this, u, b).call(this);
|
|
52
|
-
}, s(this, m)));
|
|
53
|
-
}, b = function() {
|
|
54
|
-
if (this.prune(), s(this, o).size >= s(this, w) || s(this, l).length === 0) return;
|
|
55
|
-
const t = s(this, l).map((e) => ({ request: e, priority: e.priority(e.handle) }));
|
|
56
|
-
t.sort((e, r) => e.priority - r.priority), n(this, l, []), p(this, u, z).call(this, { requests: t.map(({ request: e }) => e), controller: new AbortController() });
|
|
57
|
-
}, z = async function(t) {
|
|
58
|
-
s(this, o).add(t);
|
|
59
|
-
const { controller: e, requests: r } = t;
|
|
60
|
-
try {
|
|
61
|
-
const c = await s(this, g).call(this, r.map((d) => d.handle), e.signal);
|
|
62
|
-
if (c.length !== r.length)
|
|
63
|
-
throw new Error(`a batch of ${r.length} was answered with ${c.length}`);
|
|
64
|
-
r.forEach((d, T) => f(d, e.signal.aborted ? null : { value: c[T] }));
|
|
65
|
-
} catch (c) {
|
|
66
|
-
for (const d of r) f(d, e.signal.aborted ? null : { error: c });
|
|
67
|
-
} finally {
|
|
68
|
-
s(this, o).delete(t), s(this, l).length > 0 && p(this, u, b).call(this);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
function f(i, t) {
|
|
72
|
-
i.settled || (i.settled = !0, i.resolve(t));
|
|
73
|
-
}
|
|
74
|
-
export {
|
|
75
|
-
x as RequestScheduler
|
|
76
|
-
};
|
|
77
|
-
//# sourceMappingURL=scheduler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sources":["../../src/core/scheduler.ts"],"sourcesContent":["/**\n * loaders.gl's `RequestScheduler`, issuing a **batch** where it issues a request, with one slot:\n * DuckDB-WASM is one worker behind one port, so a second statement queues behind the first rather\n * than overlapping it, and fossil reads a run of consecutive tiles as one statement only when it is\n * handed them in one call (`/docs/design/graph`, *one batch in flight*).\n *\n * Priorities are asked again each time a slot frees, the debounce settles or `prune` runs. A negative\n * priority is a request nobody wants any more: queued, it resolves `null` without ever being issued;\n * in flight, its batch is aborted only once no request in it is wanted — a batch that still answers\n * someone finishes, and answers everyone in it.\n */\n\n/** A request's answer, its batch's failure, or `null` when it was never issued or was aborted. */\nexport type Outcome<R> = { readonly value: R } | { readonly error: unknown } | null;\n\ninterface Request<T, R> {\n readonly handle: T;\n readonly priority: (handle: T) => number;\n readonly resolve: (outcome: Outcome<R>) => void;\n settled: boolean;\n dropped: boolean;\n}\n\ninterface Flight<T, R> {\n readonly requests: readonly Request<T, R>[];\n readonly controller: AbortController;\n}\n\nexport interface SchedulerOptions<T, R> {\n /** One call for a batch: an answer per handle, in the order given. */\n run: (handles: readonly T[], signal: AbortSignal) => Promise<readonly R[]>;\n /** Batches running at once. */\n maxRequests?: number;\n /** Quiet time, in milliseconds, before the queue is issued — a pan settles before it asks. */\n debounceTime?: number;\n}\n\nexport class RequestScheduler<T, R> {\n readonly #run: SchedulerOptions<T, R>[\"run\"];\n readonly #max: number;\n readonly #debounce: number;\n #queue: Request<T, R>[] = [];\n #flights = new Set<Flight<T, R>>();\n #timer: ReturnType<typeof setTimeout> | null = null;\n\n constructor({ debounceTime = 0, maxRequests = 1, run }: SchedulerOptions<T, R>) {\n this.#run = run;\n this.#max = maxRequests;\n this.#debounce = debounceTime;\n }\n\n schedule(handle: T, priority: (handle: T) => number): Promise<Outcome<R>> {\n return new Promise((resolve) => {\n this.#queue.push({ handle, priority, resolve, settled: false, dropped: false });\n this.#wake();\n });\n }\n\n /** How many requests are queued, and how many batches are running. */\n get size(): { queued: number; active: number } {\n return { queued: this.#queue.length, active: this.#flights.size };\n }\n\n /** The caller no longer wants `handle`'s answer: it resolves `null` now, wherever it is. */\n cancel(handle: T): void {\n this.#queue = this.#queue.filter((request) => {\n if (request.handle !== handle) return true;\n settle(request, null);\n return false;\n });\n for (const flight of this.#flights) {\n for (const request of flight.requests) {\n if (request.handle !== handle) continue;\n request.dropped = true;\n settle(request, null);\n }\n }\n this.prune();\n }\n\n /** Drops queued requests nobody wants, and aborts a batch in which nobody wants anything. */\n prune(): void {\n this.#queue = this.#queue.filter((request) => {\n if (request.priority(request.handle) >= 0) return true;\n settle(request, null);\n return false;\n });\n for (const flight of this.#flights) {\n const wanted = flight.requests.some((r) => !r.dropped && r.priority(r.handle) >= 0);\n if (!wanted) flight.controller.abort();\n }\n }\n\n /** Every queued request resolves `null`, and every running batch is aborted. */\n clear(): void {\n if (this.#timer !== null) clearTimeout(this.#timer);\n this.#timer = null;\n for (const request of this.#queue) settle(request, null);\n this.#queue = [];\n for (const flight of this.#flights) flight.controller.abort();\n }\n\n #wake(): void {\n if (this.#timer !== null) clearTimeout(this.#timer);\n this.#timer = setTimeout(() => {\n this.#timer = null;\n this.#issue();\n }, this.#debounce);\n }\n\n #issue(): void {\n this.prune();\n if (this.#flights.size >= this.#max || this.#queue.length === 0) return;\n const ranked = this.#queue.map((request) => ({ request, priority: request.priority(request.handle) }));\n ranked.sort((a, b) => a.priority - b.priority);\n this.#queue = [];\n void this.#fly({ requests: ranked.map(({ request }) => request), controller: new AbortController() });\n }\n\n async #fly(flight: Flight<T, R>): Promise<void> {\n this.#flights.add(flight);\n const { controller, requests } = flight;\n try {\n const answers = await this.#run(\n requests.map((request) => request.handle),\n controller.signal,\n );\n if (answers.length !== requests.length) {\n throw new Error(`a batch of ${requests.length} was answered with ${answers.length}`);\n }\n requests.forEach((request, i) => settle(request, controller.signal.aborted ? null : { value: answers[i] as R }));\n } catch (error) {\n for (const request of requests) settle(request, controller.signal.aborted ? null : { error });\n } finally {\n this.#flights.delete(flight);\n if (this.#queue.length > 0) this.#issue();\n }\n }\n}\n\nfunction settle<T, R>(request: Request<T, R>, outcome: Outcome<R>): void {\n if (request.settled) return;\n request.settled = true;\n request.resolve(outcome);\n}\n"],"names":["_run","_max","_debounce","_queue","_flights","_timer","_RequestScheduler_instances","wake_fn","issue_fn","fly_fn","RequestScheduler","debounceTime","maxRequests","run","__privateAdd","__privateSet","handle","priority","resolve","__privateGet","__privateMethod","request","settle","flight","ranked","a","b","controller","requests","answers","i","error","outcome"],"mappings":"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"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { TileAddress, TileMatrixSet } from '@fossil-lang/corpus';
|
|
2
|
-
/** A rectangle in the corpus's own coordinates, which are the camera's. */
|
|
3
|
-
export interface Viewport {
|
|
4
|
-
xMin: number;
|
|
5
|
-
yMin: number;
|
|
6
|
-
xMax: number;
|
|
7
|
-
yMax: number;
|
|
8
|
-
}
|
|
9
|
-
/** deck.gl's `${x}-${y}-${z}`, on fossil's one-dimensional address. */
|
|
10
|
-
export declare const tileId: ({ tile, type, z }: TileAddress) => string;
|
|
11
|
-
/**
|
|
12
|
-
* The tiles of one matrix in view — deck.gl's `getTileIndices`, as a cull rather than arithmetic:
|
|
13
|
-
* where a rank falls on the plane depends on the positions, so only the published boxes can say.
|
|
14
|
-
*/
|
|
15
|
-
export declare function cull(set: TileMatrixSet, z: number, view: Viewport, among?: ReadonlySet<number>): number[];
|
|
16
|
-
/**
|
|
17
|
-
* **The finest planned `z` whose tiles in view hold, by their published `rows`, at most `limit`.**
|
|
18
|
-
*
|
|
19
|
-
* `planned` is what `scan.plan()` kept, by zoom — a filter on a payload column plans nothing below
|
|
20
|
-
* `Z`, so the choice is among the planned zooms only and a coarse camera then draws rows. When no
|
|
21
|
-
* zoom fits, the coarsest planned one is drawn.
|
|
22
|
-
*/
|
|
23
|
-
export declare function selectLevel(set: TileMatrixSet, view: Viewport, limit: number, planned: ReadonlyMap<number, ReadonlySet<number>>): {
|
|
24
|
-
z: number;
|
|
25
|
-
tiles: number[];
|
|
26
|
-
} | null;
|
|
27
|
-
/**
|
|
28
|
-
* The tile one zoom coarser that covers this one: `(z − 1, t >> (shift(z − 1) − shift(z)))`.
|
|
29
|
-
* Every zoom has the same `tileRows`, so a coarser tile covers `2^Δshift` finer ones — sixteen
|
|
30
|
-
* between the payload and the first rung, four between rungs.
|
|
31
|
-
*/
|
|
32
|
-
export declare function parentOf(set: TileMatrixSet, address: TileAddress): TileAddress | null;
|
|
33
|
-
/** The centre of a tile's box, or of the extent when it publishes none. */
|
|
34
|
-
export declare function centreOf(set: TileMatrixSet, address: TileAddress): [number, number] | null;
|
|
35
|
-
/** The payload tile a vertex's `dense_id` falls in. */
|
|
36
|
-
export declare function tileOfDense(set: TileMatrixSet, dense: number): TileAddress | null;
|
|
37
|
-
//# sourceMappingURL=tile-matrix.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tile-matrix.d.ts","sourceRoot":"","sources":["../../src/core/tile-matrix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE3E,2EAA2E;AAC3E,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,uEAAuE;AACvE,eAAO,MAAM,MAAM,GAAI,mBAAmB,WAAW,KAAG,MAAgC,CAAC;AAQzF;;;GAGG;AACH,wBAAgB,IAAI,CAClB,GAAG,EAAE,aAAa,EAClB,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,QAAQ,EACd,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAC1B,MAAM,EAAE,CASV;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,GAChD;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAYvC;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAMrF;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAG1F;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAMjF"}
|
package/dist/core/tile-matrix.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
const x = ({ tile: t, type: e, z: n }) => `${e}-${n}-${t}`;
|
|
2
|
-
function h(t, e) {
|
|
3
|
-
return t === null ? !0 : t.x <= e.xMax && t.x + t.w >= e.xMin && t.y <= e.yMax && t.y + t.h >= e.yMin;
|
|
4
|
-
}
|
|
5
|
-
function y(t, e, n, i) {
|
|
6
|
-
const l = t.tileMatrices[e];
|
|
7
|
-
if (!l) return [];
|
|
8
|
-
const o = [];
|
|
9
|
-
for (const r of l.tiles)
|
|
10
|
-
i && !i.has(r.tile) || h(r.bbox, n) && o.push(r.tile);
|
|
11
|
-
return o;
|
|
12
|
-
}
|
|
13
|
-
function z(t, e, n, i) {
|
|
14
|
-
var r, f;
|
|
15
|
-
const l = [...i.keys()].sort((s, c) => c - s);
|
|
16
|
-
let o = null;
|
|
17
|
-
for (const s of l) {
|
|
18
|
-
const c = y(t, s, e, i.get(s)), a = ((r = t.tileMatrices[s]) == null ? void 0 : r.tiles) ?? [];
|
|
19
|
-
let u = 0;
|
|
20
|
-
for (const M of c) u += ((f = a[M]) == null ? void 0 : f.rows) ?? 0;
|
|
21
|
-
if (u <= n) return { z: s, tiles: c };
|
|
22
|
-
o = { z: s, tiles: c };
|
|
23
|
-
}
|
|
24
|
-
return o;
|
|
25
|
-
}
|
|
26
|
-
function p(t, e) {
|
|
27
|
-
const { tile: n, type: i, z: l } = e, o = t.tileMatrices[l], r = t.tileMatrices[l - 1];
|
|
28
|
-
return !o || !r ? null : { type: i, z: l - 1, tile: Math.floor(n / 2 ** (r.shift - o.shift)) };
|
|
29
|
-
}
|
|
30
|
-
function m(t, e) {
|
|
31
|
-
var i, l;
|
|
32
|
-
const n = ((l = (i = t.tileMatrices[e.z]) == null ? void 0 : i.tiles[e.tile]) == null ? void 0 : l.bbox) ?? t.extent;
|
|
33
|
-
return n === null ? null : [n.x + n.w / 2, n.y + n.h / 2];
|
|
34
|
-
}
|
|
35
|
-
function O(t, e) {
|
|
36
|
-
const n = t.tileMatrices.length - 1, i = t.tileMatrices[n];
|
|
37
|
-
if (!i) return null;
|
|
38
|
-
const l = Math.floor(e / i.tileRows);
|
|
39
|
-
return l < i.tiles.length ? { type: t.type, z: n, tile: l } : null;
|
|
40
|
-
}
|
|
41
|
-
export {
|
|
42
|
-
m as centreOf,
|
|
43
|
-
y as cull,
|
|
44
|
-
p as parentOf,
|
|
45
|
-
z as selectLevel,
|
|
46
|
-
x as tileId,
|
|
47
|
-
O as tileOfDense
|
|
48
|
-
};
|
|
49
|
-
//# sourceMappingURL=tile-matrix.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tile-matrix.js","sources":["../../src/core/tile-matrix.ts"],"sourcesContent":["import type { Box, TileAddress, TileMatrixSet } from \"@fossil-lang/corpus\";\n\n/** A rectangle in the corpus's own coordinates, which are the camera's. */\nexport interface Viewport {\n xMin: number;\n yMin: number;\n xMax: number;\n yMax: number;\n}\n\n/** deck.gl's `${x}-${y}-${z}`, on fossil's one-dimensional address. */\nexport const tileId = ({ tile, type, z }: TileAddress): string => `${type}-${z}-${tile}`;\n\n/** Closed on both edges: a published box is a bound, not a selection. */\nfunction meets(box: Box | null, view: Viewport): boolean {\n if (box === null) return true;\n return box.x <= view.xMax && box.x + box.w >= view.xMin && box.y <= view.yMax && box.y + box.h >= view.yMin;\n}\n\n/**\n * The tiles of one matrix in view — deck.gl's `getTileIndices`, as a cull rather than arithmetic:\n * where a rank falls on the plane depends on the positions, so only the published boxes can say.\n */\nexport function cull(\n set: TileMatrixSet,\n z: number,\n view: Viewport,\n among?: ReadonlySet<number>,\n): number[] {\n const matrix = set.tileMatrices[z];\n if (!matrix) return [];\n const found: number[] = [];\n for (const info of matrix.tiles) {\n if (among && !among.has(info.tile)) continue;\n if (meets(info.bbox, view)) found.push(info.tile);\n }\n return found;\n}\n\n/**\n * **The finest planned `z` whose tiles in view hold, by their published `rows`, at most `limit`.**\n *\n * `planned` is what `scan.plan()` kept, by zoom — a filter on a payload column plans nothing below\n * `Z`, so the choice is among the planned zooms only and a coarse camera then draws rows. When no\n * zoom fits, the coarsest planned one is drawn.\n */\nexport function selectLevel(\n set: TileMatrixSet,\n view: Viewport,\n limit: number,\n planned: ReadonlyMap<number, ReadonlySet<number>>,\n): { z: number; tiles: number[] } | null {\n const zooms = [...planned.keys()].sort((a, b) => b - a);\n let coarsest: { z: number; tiles: number[] } | null = null;\n for (const z of zooms) {\n const tiles = cull(set, z, view, planned.get(z));\n const infos = set.tileMatrices[z]?.tiles ?? [];\n let rows = 0;\n for (const tile of tiles) rows += infos[tile]?.rows ?? 0;\n if (rows <= limit) return { z, tiles };\n coarsest = { z, tiles };\n }\n return coarsest;\n}\n\n/**\n * The tile one zoom coarser that covers this one: `(z − 1, t >> (shift(z − 1) − shift(z)))`.\n * Every zoom has the same `tileRows`, so a coarser tile covers `2^Δshift` finer ones — sixteen\n * between the payload and the first rung, four between rungs.\n */\nexport function parentOf(set: TileMatrixSet, address: TileAddress): TileAddress | null {\n const { tile, type, z } = address;\n const here = set.tileMatrices[z];\n const above = set.tileMatrices[z - 1];\n if (!here || !above) return null;\n return { type, z: z - 1, tile: Math.floor(tile / 2 ** (above.shift - here.shift)) };\n}\n\n/** The centre of a tile's box, or of the extent when it publishes none. */\nexport function centreOf(set: TileMatrixSet, address: TileAddress): [number, number] | null {\n const box = set.tileMatrices[address.z]?.tiles[address.tile]?.bbox ?? set.extent;\n return box === null ? null : [box.x + box.w / 2, box.y + box.h / 2];\n}\n\n/** The payload tile a vertex's `dense_id` falls in. */\nexport function tileOfDense(set: TileMatrixSet, dense: number): TileAddress | null {\n const z = set.tileMatrices.length - 1;\n const matrix = set.tileMatrices[z];\n if (!matrix) return null;\n const tile = Math.floor(dense / matrix.tileRows);\n return tile < matrix.tiles.length ? { type: set.type, z, tile } : null;\n}\n"],"names":["tileId","tile","type","z","meets","box","view","cull","set","among","matrix","found","info","selectLevel","limit","planned","_a","_b","zooms","a","b","coarsest","tiles","infos","rows","parentOf","address","here","above","centreOf","tileOfDense","dense"],"mappings":"AAWO,MAAMA,IAAS,CAAC,EAAE,MAAAC,GAAM,MAAAC,GAAM,GAAAC,EAAA,MAA6B,GAAGD,CAAI,IAAIC,CAAC,IAAIF,CAAI;AAGtF,SAASG,EAAMC,GAAiBC,GAAyB;AACvD,SAAID,MAAQ,OAAa,KAClBA,EAAI,KAAKC,EAAK,QAAQD,EAAI,IAAIA,EAAI,KAAKC,EAAK,QAAQD,EAAI,KAAKC,EAAK,QAAQD,EAAI,IAAIA,EAAI,KAAKC,EAAK;AACzG;AAMO,SAASC,EACdC,GACAL,GACAG,GACAG,GACU;AACV,QAAMC,IAASF,EAAI,aAAaL,CAAC;AACjC,MAAI,CAACO,EAAQ,QAAO,CAAA;AACpB,QAAMC,IAAkB,CAAA;AACxB,aAAWC,KAAQF,EAAO;AACxB,IAAID,KAAS,CAACA,EAAM,IAAIG,EAAK,IAAI,KAC7BR,EAAMQ,EAAK,MAAMN,CAAI,KAAGK,EAAM,KAAKC,EAAK,IAAI;AAElD,SAAOD;AACT;AASO,SAASE,EACdL,GACAF,GACAQ,GACAC,GACuC;AAxClC,MAAAC,GAAAC;AAyCL,QAAMC,IAAQ,CAAC,GAAGH,EAAQ,KAAA,CAAM,EAAE,KAAK,CAACI,GAAGC,MAAMA,IAAID,CAAC;AACtD,MAAIE,IAAkD;AACtD,aAAWlB,KAAKe,GAAO;AACrB,UAAMI,IAAQf,EAAKC,GAAKL,GAAGG,GAAMS,EAAQ,IAAIZ,CAAC,CAAC,GACzCoB,MAAQP,IAAAR,EAAI,aAAaL,CAAC,MAAlB,gBAAAa,EAAqB,UAAS,CAAA;AAC5C,QAAIQ,IAAO;AACX,eAAWvB,KAAQqB,EAAO,CAAAE,OAAQP,IAAAM,EAAMtB,CAAI,MAAV,gBAAAgB,EAAa,SAAQ;AACvD,QAAIO,KAAQV,EAAO,QAAO,EAAE,GAAAX,GAAG,OAAAmB,EAAA;AAC/B,IAAAD,IAAW,EAAE,GAAAlB,GAAG,OAAAmB,EAAA;AAAA,EAClB;AACA,SAAOD;AACT;AAOO,SAASI,EAASjB,GAAoBkB,GAA0C;AACrF,QAAM,EAAE,MAAAzB,GAAM,MAAAC,GAAM,GAAAC,EAAA,IAAMuB,GACpBC,IAAOnB,EAAI,aAAaL,CAAC,GACzByB,IAAQpB,EAAI,aAAaL,IAAI,CAAC;AACpC,SAAI,CAACwB,KAAQ,CAACC,IAAc,OACrB,EAAE,MAAA1B,GAAM,GAAGC,IAAI,GAAG,MAAM,KAAK,MAAMF,IAAO,MAAM2B,EAAM,QAAQD,EAAK,MAAM,EAAA;AAClF;AAGO,SAASE,EAASrB,GAAoBkB,GAA+C;AApErF,MAAAV,GAAAC;AAqEL,QAAMZ,MAAMY,KAAAD,IAAAR,EAAI,aAAakB,EAAQ,CAAC,MAA1B,gBAAAV,EAA6B,MAAMU,EAAQ,UAA3C,gBAAAT,EAAkD,SAAQT,EAAI;AAC1E,SAAOH,MAAQ,OAAO,OAAO,CAACA,EAAI,IAAIA,EAAI,IAAI,GAAGA,EAAI,IAAIA,EAAI,IAAI,CAAC;AACpE;AAGO,SAASyB,EAAYtB,GAAoBuB,GAAmC;AACjF,QAAM5B,IAAIK,EAAI,aAAa,SAAS,GAC9BE,IAASF,EAAI,aAAaL,CAAC;AACjC,MAAI,CAACO,EAAQ,QAAO;AACpB,QAAMT,IAAO,KAAK,MAAM8B,IAAQrB,EAAO,QAAQ;AAC/C,SAAOT,IAAOS,EAAO,MAAM,SAAS,EAAE,MAAMF,EAAI,MAAM,GAAAL,GAAG,MAAAF,EAAA,IAAS;AACpE;"}
|
package/dist/core/tile.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { Batch, EdgeBatch, Gap, TileAddress } from '@fossil-lang/corpus';
|
|
2
|
-
import { RequestScheduler } from './scheduler';
|
|
3
|
-
/** What one tile holds once read: its rows, the relations incident to it, and what was declined. */
|
|
4
|
-
export interface TileContent {
|
|
5
|
-
readonly rows: Batch;
|
|
6
|
-
readonly edges: readonly EdgeBatch[];
|
|
7
|
-
readonly declined: readonly Gap[];
|
|
8
|
-
readonly byteLength: number;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* deck.gl's `getTileData`, over a batch: fossil's addresses where deck.gl has `{ x, y, z }`, and one
|
|
12
|
-
* content per address, in order, because the corpus reads a run of consecutive tiles in one statement.
|
|
13
|
-
*/
|
|
14
|
-
export type TileLoader = (addresses: readonly TileAddress[], signal: AbortSignal) => Promise<readonly TileContent[]>;
|
|
15
|
-
export interface TileLoad {
|
|
16
|
-
scheduler: RequestScheduler<Tile, TileContent>;
|
|
17
|
-
priority: (tile: Tile) => number;
|
|
18
|
-
onLoad: (tile: Tile) => void;
|
|
19
|
-
onError: (error: unknown, tile: Tile) => void;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* deck.gl's `Tile2DHeader`: one tile's load, abort and content, and its place in the tree.
|
|
23
|
-
*
|
|
24
|
-
* **Content outlives a reload.** A tile marked for reload keeps what it last read until the new
|
|
25
|
-
* answer arrives, and an aborted or failed reload keeps it too, so a change of question never
|
|
26
|
-
* shows a hole. deck.gl drops it on a cancelled reload; the one departure, and it is what
|
|
27
|
-
* `/docs/design/graph` asks of a change of data.
|
|
28
|
-
*/
|
|
29
|
-
export declare class Tile {
|
|
30
|
-
#private;
|
|
31
|
-
readonly address: TileAddress;
|
|
32
|
-
readonly id: string;
|
|
33
|
-
content: TileContent | null;
|
|
34
|
-
isSelected: boolean;
|
|
35
|
-
isVisible: boolean;
|
|
36
|
-
parent: Tile | null;
|
|
37
|
-
children: Tile[];
|
|
38
|
-
constructor(address: TileAddress);
|
|
39
|
-
get z(): number;
|
|
40
|
-
/** Read at least once for the current question. */
|
|
41
|
-
get isLoaded(): boolean;
|
|
42
|
-
/** Queued or running, and not cancelled. */
|
|
43
|
-
get isLoading(): boolean;
|
|
44
|
-
get needsReload(): boolean;
|
|
45
|
-
get byteLength(): number;
|
|
46
|
-
loadData(options: TileLoad): Promise<void>;
|
|
47
|
-
/**
|
|
48
|
-
* A finished tile has nothing to abort; a queued or running one is cancelled, and its batch is
|
|
49
|
-
* aborted once no tile in it is wanted.
|
|
50
|
-
*/
|
|
51
|
-
abort(): void;
|
|
52
|
-
setNeedsReload(): void;
|
|
53
|
-
}
|
|
54
|
-
//# sourceMappingURL=tile.d.ts.map
|
package/dist/core/tile.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tile.d.ts","sourceRoot":"","sources":["../../src/core/tile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,oGAAoG;AACpG,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,SAAS,GAAG,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,SAAS,WAAW,EAAE,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC;AAErH,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC/C,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IACjC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC7B,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;GAOG;AACH,qBAAa,IAAI;;IACf,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,WAAW,GAAG,IAAI,CAAQ;IACnC,UAAU,UAAS;IACnB,SAAS,UAAS;IAClB,MAAM,EAAE,IAAI,GAAG,IAAI,CAAQ;IAC3B,QAAQ,EAAE,IAAI,EAAE,CAAM;gBASV,OAAO,EAAE,WAAW;IAKhC,IAAI,CAAC,IAAI,MAAM,CAEd;IAED,mDAAmD;IACnD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,4CAA4C;IAC5C,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1C;;;OAGG;IACH,KAAK,IAAI,IAAI;IAMb,cAAc,IAAI,IAAI;CAyBvB"}
|