styled-map-package-api 5.0.0-pre.1 → 5.0.0-pre.3
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 +7 -0
- package/dist/download.d.cts +1 -1
- package/dist/download.d.ts +1 -1
- package/dist/from-mbtiles.cjs +86 -40
- package/dist/from-mbtiles.d.cts +7 -3
- package/dist/from-mbtiles.d.ts +7 -3
- package/dist/from-mbtiles.js +86 -40
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/reader.cjs +1 -1
- package/dist/reader.d.cts +1 -1
- package/dist/reader.d.ts +1 -1
- package/dist/reader.js +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/style-downloader.d.cts +1 -1
- package/dist/style-downloader.d.ts +1 -1
- package/dist/tile-downloader.d.cts +1 -1
- package/dist/tile-downloader.d.ts +1 -1
- package/dist/{types-DPei6PMF.d.cts → types-Bhn0-Ldk.d.cts} +20 -2
- package/dist/{types-DPei6PMF.d.ts → types-Bhn0-Ldk.d.ts} +20 -2
- package/dist/utils/file-formats.d.cts +1 -1
- package/dist/utils/file-formats.d.ts +1 -1
- package/dist/utils/style.d.cts +1 -1
- package/dist/utils/style.d.ts +1 -1
- package/dist/utils/templates.d.cts +1 -1
- package/dist/utils/templates.d.ts +1 -1
- package/dist/writer.cjs +78 -2
- package/dist/writer.d.cts +1 -1
- package/dist/writer.d.ts +1 -1
- package/dist/writer.js +68 -2
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -58,10 +58,17 @@ const stream = download({
|
|
|
58
58
|
|
|
59
59
|
### Converting from MBTiles
|
|
60
60
|
|
|
61
|
+
> **Note:** MBTiles conversion requires Node >= 20 (uses `better-sqlite3` which dropped Node 18 support).
|
|
62
|
+
|
|
61
63
|
```js
|
|
62
64
|
import { fromMBTiles } from 'styled-map-package-api/from-mbtiles'
|
|
63
65
|
|
|
66
|
+
// From a file path (Node.js)
|
|
64
67
|
const stream = fromMBTiles('path/to/tiles.mbtiles')
|
|
68
|
+
|
|
69
|
+
// From an ArrayBuffer or Uint8Array (Node.js and browsers)
|
|
70
|
+
const stream = fromMBTiles(buffer)
|
|
71
|
+
|
|
65
72
|
// Pipe the ReadableStream to an .smp file
|
|
66
73
|
```
|
|
67
74
|
|
package/dist/download.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GlyphDownloadStats } from './style-downloader.cjs';
|
|
2
2
|
import { TileDownloadStats } from './tile-downloader.cjs';
|
|
3
|
-
import { D as DownloadStream } from './types-
|
|
3
|
+
import { D as DownloadStream } from './types-Bhn0-Ldk.cjs';
|
|
4
4
|
import { BBox } from './utils/geo.cjs';
|
|
5
5
|
import 'ky';
|
|
6
6
|
import '@maplibre/maplibre-gl-style-spec';
|
package/dist/download.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GlyphDownloadStats } from './style-downloader.js';
|
|
2
2
|
import { TileDownloadStats } from './tile-downloader.js';
|
|
3
|
-
import { D as DownloadStream } from './types-
|
|
3
|
+
import { D as DownloadStream } from './types-Bhn0-Ldk.js';
|
|
4
4
|
import { BBox } from './utils/geo.js';
|
|
5
5
|
import 'ky';
|
|
6
6
|
import '@maplibre/maplibre-gl-style-spec';
|
package/dist/from-mbtiles.cjs
CHANGED
|
@@ -22,53 +22,99 @@ __export(from_mbtiles_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(from_mbtiles_exports);
|
|
24
24
|
var import_mbtiles_reader = require("mbtiles-reader");
|
|
25
|
+
var import_misc = require('./utils/misc.cjs');
|
|
25
26
|
var import_streams = require('./utils/streams.cjs');
|
|
26
27
|
var import_writer = require('./writer.cjs');
|
|
27
28
|
const SOURCE_ID = "mbtiles-source";
|
|
28
|
-
function fromMBTiles(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
[SOURCE_ID]: {
|
|
38
|
-
...reader.metadata,
|
|
39
|
-
type: "raster"
|
|
29
|
+
function fromMBTiles(source) {
|
|
30
|
+
let outputReader;
|
|
31
|
+
let conversionDone;
|
|
32
|
+
const pipeAbort = new AbortController();
|
|
33
|
+
return new ReadableStream({
|
|
34
|
+
async start() {
|
|
35
|
+
const reader = await import_mbtiles_reader.MBTiles.open(source);
|
|
36
|
+
if (reader.metadata.format === "pbf") {
|
|
37
|
+
throw new Error("Vector MBTiles are not yet supported");
|
|
40
38
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
{
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
39
|
+
const {
|
|
40
|
+
name,
|
|
41
|
+
minzoom,
|
|
42
|
+
maxzoom,
|
|
43
|
+
scheme,
|
|
44
|
+
attribution,
|
|
45
|
+
description,
|
|
46
|
+
version: tilesetVersion
|
|
47
|
+
} = reader.metadata;
|
|
48
|
+
const style = {
|
|
49
|
+
version: 8,
|
|
50
|
+
name,
|
|
51
|
+
sources: {
|
|
52
|
+
[SOURCE_ID]: {
|
|
53
|
+
type: "raster",
|
|
54
|
+
tileSize: 256,
|
|
55
|
+
minzoom,
|
|
56
|
+
maxzoom,
|
|
57
|
+
scheme,
|
|
58
|
+
attribution
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
layers: [
|
|
62
|
+
{
|
|
63
|
+
id: "background",
|
|
64
|
+
type: "background",
|
|
65
|
+
paint: {
|
|
66
|
+
"background-color": "white"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "raster",
|
|
71
|
+
type: "raster",
|
|
72
|
+
source: SOURCE_ID,
|
|
73
|
+
paint: {
|
|
74
|
+
"raster-opacity": 1
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
if (description || tilesetVersion) {
|
|
80
|
+
style.metadata = {
|
|
81
|
+
"mbtiles:description": description,
|
|
82
|
+
"mbtiles:version": tilesetVersion
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const writer = new import_writer.Writer(style);
|
|
86
|
+
outputReader = writer.outputStream.getReader();
|
|
87
|
+
conversionDone = (async () => {
|
|
88
|
+
try {
|
|
89
|
+
await (0, import_streams.readableFromAsync)(mbtilesToTileArgs(reader)).pipeTo(
|
|
90
|
+
writer.createTileWriteStream(),
|
|
91
|
+
{ signal: pipeAbort.signal }
|
|
92
|
+
);
|
|
93
|
+
writer.finish();
|
|
94
|
+
} catch (err) {
|
|
95
|
+
try {
|
|
96
|
+
writer.abort(err instanceof Error ? err : new Error(String(err)));
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
56
99
|
}
|
|
100
|
+
})();
|
|
101
|
+
},
|
|
102
|
+
async pull(controller) {
|
|
103
|
+
const { done, value } = await /** @type {ReadableStreamDefaultReader<Uint8Array>} */
|
|
104
|
+
outputReader.read();
|
|
105
|
+
if (done) {
|
|
106
|
+
controller.close();
|
|
107
|
+
} else {
|
|
108
|
+
controller.enqueue(value);
|
|
57
109
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
writer.createTileWriteStream()
|
|
65
|
-
);
|
|
66
|
-
writer.finish();
|
|
67
|
-
} catch (err) {
|
|
68
|
-
writer.abort(err instanceof Error ? err : new Error(String(err)));
|
|
110
|
+
},
|
|
111
|
+
async cancel(reason) {
|
|
112
|
+
pipeAbort.abort(reason);
|
|
113
|
+
await conversionDone;
|
|
114
|
+
await /** @type {ReadableStreamDefaultReader<Uint8Array>} */
|
|
115
|
+
outputReader.cancel(reason).catch(import_misc.noop);
|
|
69
116
|
}
|
|
70
|
-
})
|
|
71
|
-
return writer.outputStream;
|
|
117
|
+
});
|
|
72
118
|
}
|
|
73
119
|
async function* mbtilesToTileArgs(mbtiles) {
|
|
74
120
|
for (const { z, x, y, data, format } of mbtiles) {
|
package/dist/from-mbtiles.d.cts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Convert a MBTiles file to a styled map package, returned as a web
|
|
3
|
-
* ReadableStream.
|
|
3
|
+
* ReadableStream. The async MBTiles.open() happens lazily inside the
|
|
4
|
+
* stream's start(), so this function is synchronous.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
+
* Requires Node >= 20 (uses better-sqlite3 which dropped Node 18 support).
|
|
7
|
+
*
|
|
8
|
+
* @param {string | ArrayBuffer | Uint8Array} source MBTiles source — file path
|
|
9
|
+
* (Node), OPFS path (browser Worker), or in-memory buffer.
|
|
6
10
|
* @returns {ReadableStream<Uint8Array>}
|
|
7
11
|
*/
|
|
8
|
-
declare function fromMBTiles(
|
|
12
|
+
declare function fromMBTiles(source: string | ArrayBuffer | Uint8Array): ReadableStream<Uint8Array>;
|
|
9
13
|
|
|
10
14
|
export { fromMBTiles };
|
package/dist/from-mbtiles.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Convert a MBTiles file to a styled map package, returned as a web
|
|
3
|
-
* ReadableStream.
|
|
3
|
+
* ReadableStream. The async MBTiles.open() happens lazily inside the
|
|
4
|
+
* stream's start(), so this function is synchronous.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
+
* Requires Node >= 20 (uses better-sqlite3 which dropped Node 18 support).
|
|
7
|
+
*
|
|
8
|
+
* @param {string | ArrayBuffer | Uint8Array} source MBTiles source — file path
|
|
9
|
+
* (Node), OPFS path (browser Worker), or in-memory buffer.
|
|
6
10
|
* @returns {ReadableStream<Uint8Array>}
|
|
7
11
|
*/
|
|
8
|
-
declare function fromMBTiles(
|
|
12
|
+
declare function fromMBTiles(source: string | ArrayBuffer | Uint8Array): ReadableStream<Uint8Array>;
|
|
9
13
|
|
|
10
14
|
export { fromMBTiles };
|
package/dist/from-mbtiles.js
CHANGED
|
@@ -1,51 +1,97 @@
|
|
|
1
1
|
import { MBTiles } from "mbtiles-reader";
|
|
2
|
+
import { noop } from "./utils/misc.js";
|
|
2
3
|
import { readableFromAsync } from "./utils/streams.js";
|
|
3
4
|
import { Writer } from "./writer.js";
|
|
4
5
|
const SOURCE_ID = "mbtiles-source";
|
|
5
|
-
function fromMBTiles(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
[SOURCE_ID]: {
|
|
15
|
-
...reader.metadata,
|
|
16
|
-
type: "raster"
|
|
6
|
+
function fromMBTiles(source) {
|
|
7
|
+
let outputReader;
|
|
8
|
+
let conversionDone;
|
|
9
|
+
const pipeAbort = new AbortController();
|
|
10
|
+
return new ReadableStream({
|
|
11
|
+
async start() {
|
|
12
|
+
const reader = await MBTiles.open(source);
|
|
13
|
+
if (reader.metadata.format === "pbf") {
|
|
14
|
+
throw new Error("Vector MBTiles are not yet supported");
|
|
17
15
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
16
|
+
const {
|
|
17
|
+
name,
|
|
18
|
+
minzoom,
|
|
19
|
+
maxzoom,
|
|
20
|
+
scheme,
|
|
21
|
+
attribution,
|
|
22
|
+
description,
|
|
23
|
+
version: tilesetVersion
|
|
24
|
+
} = reader.metadata;
|
|
25
|
+
const style = {
|
|
26
|
+
version: 8,
|
|
27
|
+
name,
|
|
28
|
+
sources: {
|
|
29
|
+
[SOURCE_ID]: {
|
|
30
|
+
type: "raster",
|
|
31
|
+
tileSize: 256,
|
|
32
|
+
minzoom,
|
|
33
|
+
maxzoom,
|
|
34
|
+
scheme,
|
|
35
|
+
attribution
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
layers: [
|
|
39
|
+
{
|
|
40
|
+
id: "background",
|
|
41
|
+
type: "background",
|
|
42
|
+
paint: {
|
|
43
|
+
"background-color": "white"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "raster",
|
|
48
|
+
type: "raster",
|
|
49
|
+
source: SOURCE_ID,
|
|
50
|
+
paint: {
|
|
51
|
+
"raster-opacity": 1
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
};
|
|
56
|
+
if (description || tilesetVersion) {
|
|
57
|
+
style.metadata = {
|
|
58
|
+
"mbtiles:description": description,
|
|
59
|
+
"mbtiles:version": tilesetVersion
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const writer = new Writer(style);
|
|
63
|
+
outputReader = writer.outputStream.getReader();
|
|
64
|
+
conversionDone = (async () => {
|
|
65
|
+
try {
|
|
66
|
+
await readableFromAsync(mbtilesToTileArgs(reader)).pipeTo(
|
|
67
|
+
writer.createTileWriteStream(),
|
|
68
|
+
{ signal: pipeAbort.signal }
|
|
69
|
+
);
|
|
70
|
+
writer.finish();
|
|
71
|
+
} catch (err) {
|
|
72
|
+
try {
|
|
73
|
+
writer.abort(err instanceof Error ? err : new Error(String(err)));
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
33
76
|
}
|
|
77
|
+
})();
|
|
78
|
+
},
|
|
79
|
+
async pull(controller) {
|
|
80
|
+
const { done, value } = await /** @type {ReadableStreamDefaultReader<Uint8Array>} */
|
|
81
|
+
outputReader.read();
|
|
82
|
+
if (done) {
|
|
83
|
+
controller.close();
|
|
84
|
+
} else {
|
|
85
|
+
controller.enqueue(value);
|
|
34
86
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
writer.createTileWriteStream()
|
|
42
|
-
);
|
|
43
|
-
writer.finish();
|
|
44
|
-
} catch (err) {
|
|
45
|
-
writer.abort(err instanceof Error ? err : new Error(String(err)));
|
|
87
|
+
},
|
|
88
|
+
async cancel(reason) {
|
|
89
|
+
pipeAbort.abort(reason);
|
|
90
|
+
await conversionDone;
|
|
91
|
+
await /** @type {ReadableStreamDefaultReader<Uint8Array>} */
|
|
92
|
+
outputReader.cancel(reason).catch(noop);
|
|
46
93
|
}
|
|
47
|
-
})
|
|
48
|
-
return writer.outputStream;
|
|
94
|
+
});
|
|
49
95
|
}
|
|
50
96
|
async function* mbtilesToTileArgs(mbtiles) {
|
|
51
97
|
for (const { z, x, y, data, format } of mbtiles) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SMPSource$1, a as SMPStyle$1 } from './types-
|
|
2
|
-
export { W as Writer } from './types-
|
|
1
|
+
import { S as SMPSource$1, a as SMPStyle$1 } from './types-Bhn0-Ldk.cjs';
|
|
2
|
+
export { W as Writer } from './types-Bhn0-Ldk.cjs';
|
|
3
3
|
export { Reader } from './reader.cjs';
|
|
4
4
|
export { createServer } from './server.cjs';
|
|
5
5
|
export { StyleDownloader } from './style-downloader.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SMPSource$1, a as SMPStyle$1 } from './types-
|
|
2
|
-
export { W as Writer } from './types-
|
|
1
|
+
import { S as SMPSource$1, a as SMPStyle$1 } from './types-Bhn0-Ldk.js';
|
|
2
|
+
export { W as Writer } from './types-Bhn0-Ldk.js';
|
|
3
3
|
export { Reader } from './reader.js';
|
|
4
4
|
export { createServer } from './server.js';
|
|
5
5
|
export { StyleDownloader } from './style-downloader.js';
|
package/dist/reader.cjs
CHANGED
|
@@ -155,7 +155,7 @@ class Reader {
|
|
|
155
155
|
sourcePromise.catch(import_misc.noop);
|
|
156
156
|
zipPromise = sourcePromise.then((source) => {
|
|
157
157
|
this.#fileSource = source;
|
|
158
|
-
return import_zip_reader.ZipReader.from(source);
|
|
158
|
+
return import_zip_reader.ZipReader.from(source, { skipUniqueEntryCheck: true });
|
|
159
159
|
});
|
|
160
160
|
} else {
|
|
161
161
|
zipPromise = Promise.resolve(filepathOrZip);
|
package/dist/reader.d.cts
CHANGED
package/dist/reader.d.ts
CHANGED
package/dist/reader.js
CHANGED
|
@@ -128,7 +128,7 @@ class Reader {
|
|
|
128
128
|
sourcePromise.catch(noop);
|
|
129
129
|
zipPromise = sourcePromise.then((source) => {
|
|
130
130
|
this.#fileSource = source;
|
|
131
|
-
return ZipReader.from(source);
|
|
131
|
+
return ZipReader.from(source, { skipUniqueEntryCheck: true });
|
|
132
132
|
});
|
|
133
133
|
} else {
|
|
134
134
|
zipPromise = Promise.resolve(filepathOrZip);
|
package/dist/server.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RequestLike } from 'itty-router';
|
|
2
2
|
import { Reader } from './reader.cjs';
|
|
3
3
|
import { IttyRouter } from 'itty-router/IttyRouter';
|
|
4
|
-
import './types-
|
|
4
|
+
import './types-Bhn0-Ldk.cjs';
|
|
5
5
|
import '@maplibre/maplibre-gl-style-spec';
|
|
6
6
|
import 'geojson';
|
|
7
7
|
import 'type-fest';
|
package/dist/server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RequestLike } from 'itty-router';
|
|
2
2
|
import { Reader } from './reader.js';
|
|
3
3
|
import { IttyRouter } from 'itty-router/IttyRouter';
|
|
4
|
-
import './types-
|
|
4
|
+
import './types-Bhn0-Ldk.js';
|
|
5
5
|
import '@maplibre/maplibre-gl-style-spec';
|
|
6
6
|
import 'geojson';
|
|
7
7
|
import 'type-fest';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ky from 'ky';
|
|
2
2
|
import { BBox } from './utils/geo.cjs';
|
|
3
|
-
import { b as StyleInlinedSources, G as GlyphInfo, T as TileInfo } from './types-
|
|
3
|
+
import { b as StyleInlinedSources, G as GlyphInfo, T as TileInfo } from './types-Bhn0-Ldk.cjs';
|
|
4
4
|
import { TileDownloadStats } from './tile-downloader.cjs';
|
|
5
5
|
import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec';
|
|
6
6
|
import 'geojson';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ky from 'ky';
|
|
2
2
|
import { BBox } from './utils/geo.js';
|
|
3
|
-
import { b as StyleInlinedSources, G as GlyphInfo, T as TileInfo } from './types-
|
|
3
|
+
import { b as StyleInlinedSources, G as GlyphInfo, T as TileInfo } from './types-Bhn0-Ldk.js';
|
|
4
4
|
import { TileDownloadStats } from './tile-downloader.js';
|
|
5
5
|
import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec';
|
|
6
6
|
import 'geojson';
|
|
@@ -27,6 +27,13 @@ import { SetRequired } from 'type-fest';
|
|
|
27
27
|
/** @import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec' */
|
|
28
28
|
/** @import { InputSource, SMPSource } from './types.js' */
|
|
29
29
|
declare const SUPPORTED_SOURCE_TYPES: readonly ["raster", "vector", "geojson"];
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {object} WriterOptions
|
|
32
|
+
* @property {boolean} [dedupe] When true, duplicate tiles (with identical
|
|
33
|
+
* content) are stored only once in the archive. Additional entries in the
|
|
34
|
+
* central directory point to the same data. This reduces file size for
|
|
35
|
+
* tilesets with many repeated tiles (e.g. ocean tiles).
|
|
36
|
+
*/
|
|
30
37
|
/**
|
|
31
38
|
* Write a styled map package to a stream. Stream `writer.outputStream` to a
|
|
32
39
|
* destination, e.g. `fs.createWriteStream('my-map.styledmap')`. You must call
|
|
@@ -39,8 +46,9 @@ declare class Writer {
|
|
|
39
46
|
* @param {any} style A v7 or v8 MapLibre style. v7 styles will be migrated to
|
|
40
47
|
* v8. (There are currently no typescript declarations for v7 styles, hence
|
|
41
48
|
* this is typed as `any` and validated internally)
|
|
49
|
+
* @param {WriterOptions} [options]
|
|
42
50
|
*/
|
|
43
|
-
constructor(style: any);
|
|
51
|
+
constructor(style: any, { dedupe }?: WriterOptions);
|
|
44
52
|
/**
|
|
45
53
|
* @returns {ReadableStream<Uint8Array>} Readable stream of the styled map package
|
|
46
54
|
*/
|
|
@@ -131,6 +139,15 @@ type GlyphInfo = {
|
|
|
131
139
|
font: string;
|
|
132
140
|
range: GlyphRange;
|
|
133
141
|
};
|
|
142
|
+
type WriterOptions = {
|
|
143
|
+
/**
|
|
144
|
+
* When true, duplicate tiles (with identical
|
|
145
|
+
* content) are stored only once in the archive. Additional entries in the
|
|
146
|
+
* central directory point to the same data. This reduces file size for
|
|
147
|
+
* tilesets with many repeated tiles (e.g. ocean tiles).
|
|
148
|
+
*/
|
|
149
|
+
dedupe?: boolean | undefined;
|
|
150
|
+
};
|
|
134
151
|
|
|
135
152
|
type TransformInlinedSource<T extends SourceSpecification> = T extends GeoJSONSourceSpecification ? OmitUnion<T, 'data'> & {
|
|
136
153
|
data: GeoJSON;
|
|
@@ -172,6 +189,7 @@ type TransformSMPStyle<T extends StyleSpecification> = Omit<T, 'sources'> & {
|
|
|
172
189
|
'smp:sourceFolders': {
|
|
173
190
|
[_: string]: string;
|
|
174
191
|
};
|
|
192
|
+
[key: string]: unknown;
|
|
175
193
|
};
|
|
176
194
|
sources: {
|
|
177
195
|
[_: string]: SMPSource;
|
|
@@ -180,4 +198,4 @@ type TransformSMPStyle<T extends StyleSpecification> = Omit<T, 'sources'> & {
|
|
|
180
198
|
type DownloadStream = ReadableStream<Uint8Array>;
|
|
181
199
|
type OmitUnion<T, K extends keyof any> = T extends unknown ? Omit<T, K> : never;
|
|
182
200
|
|
|
183
|
-
export { type DownloadStream as D, type GlyphInfo as G, type InlinedSource as I, type SMPSource as S, type TileInfo as T, Writer as W, type SMPStyle as a, type StyleInlinedSources as b, type TileFormat as c, type GlyphRange as d, SUPPORTED_SOURCE_TYPES as e, type Source as f, type SourceInfo as g };
|
|
201
|
+
export { type DownloadStream as D, type GlyphInfo as G, type InlinedSource as I, type SMPSource as S, type TileInfo as T, Writer as W, type SMPStyle as a, type StyleInlinedSources as b, type TileFormat as c, type GlyphRange as d, SUPPORTED_SOURCE_TYPES as e, type Source as f, type SourceInfo as g, type WriterOptions as h };
|
|
@@ -27,6 +27,13 @@ import { SetRequired } from 'type-fest';
|
|
|
27
27
|
/** @import { StyleSpecification } from '@maplibre/maplibre-gl-style-spec' */
|
|
28
28
|
/** @import { InputSource, SMPSource } from './types.js' */
|
|
29
29
|
declare const SUPPORTED_SOURCE_TYPES: readonly ["raster", "vector", "geojson"];
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {object} WriterOptions
|
|
32
|
+
* @property {boolean} [dedupe] When true, duplicate tiles (with identical
|
|
33
|
+
* content) are stored only once in the archive. Additional entries in the
|
|
34
|
+
* central directory point to the same data. This reduces file size for
|
|
35
|
+
* tilesets with many repeated tiles (e.g. ocean tiles).
|
|
36
|
+
*/
|
|
30
37
|
/**
|
|
31
38
|
* Write a styled map package to a stream. Stream `writer.outputStream` to a
|
|
32
39
|
* destination, e.g. `fs.createWriteStream('my-map.styledmap')`. You must call
|
|
@@ -39,8 +46,9 @@ declare class Writer {
|
|
|
39
46
|
* @param {any} style A v7 or v8 MapLibre style. v7 styles will be migrated to
|
|
40
47
|
* v8. (There are currently no typescript declarations for v7 styles, hence
|
|
41
48
|
* this is typed as `any` and validated internally)
|
|
49
|
+
* @param {WriterOptions} [options]
|
|
42
50
|
*/
|
|
43
|
-
constructor(style: any);
|
|
51
|
+
constructor(style: any, { dedupe }?: WriterOptions);
|
|
44
52
|
/**
|
|
45
53
|
* @returns {ReadableStream<Uint8Array>} Readable stream of the styled map package
|
|
46
54
|
*/
|
|
@@ -131,6 +139,15 @@ type GlyphInfo = {
|
|
|
131
139
|
font: string;
|
|
132
140
|
range: GlyphRange;
|
|
133
141
|
};
|
|
142
|
+
type WriterOptions = {
|
|
143
|
+
/**
|
|
144
|
+
* When true, duplicate tiles (with identical
|
|
145
|
+
* content) are stored only once in the archive. Additional entries in the
|
|
146
|
+
* central directory point to the same data. This reduces file size for
|
|
147
|
+
* tilesets with many repeated tiles (e.g. ocean tiles).
|
|
148
|
+
*/
|
|
149
|
+
dedupe?: boolean | undefined;
|
|
150
|
+
};
|
|
134
151
|
|
|
135
152
|
type TransformInlinedSource<T extends SourceSpecification> = T extends GeoJSONSourceSpecification ? OmitUnion<T, 'data'> & {
|
|
136
153
|
data: GeoJSON;
|
|
@@ -172,6 +189,7 @@ type TransformSMPStyle<T extends StyleSpecification> = Omit<T, 'sources'> & {
|
|
|
172
189
|
'smp:sourceFolders': {
|
|
173
190
|
[_: string]: string;
|
|
174
191
|
};
|
|
192
|
+
[key: string]: unknown;
|
|
175
193
|
};
|
|
176
194
|
sources: {
|
|
177
195
|
[_: string]: SMPSource;
|
|
@@ -180,4 +198,4 @@ type TransformSMPStyle<T extends StyleSpecification> = Omit<T, 'sources'> & {
|
|
|
180
198
|
type DownloadStream = ReadableStream<Uint8Array>;
|
|
181
199
|
type OmitUnion<T, K extends keyof any> = T extends unknown ? Omit<T, K> : never;
|
|
182
200
|
|
|
183
|
-
export { type DownloadStream as D, type GlyphInfo as G, type InlinedSource as I, type SMPSource as S, type TileInfo as T, Writer as W, type SMPStyle as a, type StyleInlinedSources as b, type TileFormat as c, type GlyphRange as d, SUPPORTED_SOURCE_TYPES as e, type Source as f, type SourceInfo as g };
|
|
201
|
+
export { type DownloadStream as D, type GlyphInfo as G, type InlinedSource as I, type SMPSource as S, type TileInfo as T, Writer as W, type SMPStyle as a, type StyleInlinedSources as b, type TileFormat as c, type GlyphRange as d, SUPPORTED_SOURCE_TYPES as e, type Source as f, type SourceInfo as g, type WriterOptions as h };
|
package/dist/utils/style.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BBox } from './geo.cjs';
|
|
2
|
-
import { I as InlinedSource } from '../types-
|
|
2
|
+
import { I as InlinedSource } from '../types-Bhn0-Ldk.cjs';
|
|
3
3
|
import * as _maplibre_maplibre_gl_style_spec from '@maplibre/maplibre-gl-style-spec';
|
|
4
4
|
import { StyleSpecification, ValidationError } from '@maplibre/maplibre-gl-style-spec';
|
|
5
5
|
import 'geojson';
|
package/dist/utils/style.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BBox } from './geo.js';
|
|
2
|
-
import { I as InlinedSource } from '../types-
|
|
2
|
+
import { I as InlinedSource } from '../types-Bhn0-Ldk.js';
|
|
3
3
|
import * as _maplibre_maplibre_gl_style_spec from '@maplibre/maplibre-gl-style-spec';
|
|
4
4
|
import { StyleSpecification, ValidationError } from '@maplibre/maplibre-gl-style-spec';
|
|
5
5
|
import 'geojson';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as type_fest from 'type-fest';
|
|
2
|
-
import { d as GlyphRange, T as TileInfo, c as TileFormat } from '../types-
|
|
2
|
+
import { d as GlyphRange, T as TileInfo, c as TileFormat } from '../types-Bhn0-Ldk.cjs';
|
|
3
3
|
import '@maplibre/maplibre-gl-style-spec';
|
|
4
4
|
import 'geojson';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as type_fest from 'type-fest';
|
|
2
|
-
import { d as GlyphRange, T as TileInfo, c as TileFormat } from '../types-
|
|
2
|
+
import { d as GlyphRange, T as TileInfo, c as TileFormat } from '../types-Bhn0-Ldk.js';
|
|
3
3
|
import '@maplibre/maplibre-gl-style-spec';
|
|
4
4
|
import 'geojson';
|
|
5
5
|
|
package/dist/writer.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
var writer_exports = {};
|
|
20
30
|
__export(writer_exports, {
|
|
@@ -56,13 +66,20 @@ class Writer {
|
|
|
56
66
|
#outputStream;
|
|
57
67
|
/** @type {ReadableStreamDefaultController<Uint8Array>} */
|
|
58
68
|
#outputController;
|
|
69
|
+
/** @type {boolean} */
|
|
70
|
+
#dedupe;
|
|
71
|
+
/** @type {Map<string, string>} hash → first entry name */
|
|
72
|
+
#tileHashes = /* @__PURE__ */ new Map();
|
|
73
|
+
/** @type {Array<{ name: string, originalName: string }>} */
|
|
74
|
+
#duplicateEntries = [];
|
|
59
75
|
static SUPPORTED_SOURCE_TYPES = SUPPORTED_SOURCE_TYPES;
|
|
60
76
|
/**
|
|
61
77
|
* @param {any} style A v7 or v8 MapLibre style. v7 styles will be migrated to
|
|
62
78
|
* v8. (There are currently no typescript declarations for v7 styles, hence
|
|
63
79
|
* this is typed as `any` and validated internally)
|
|
80
|
+
* @param {WriterOptions} [options]
|
|
64
81
|
*/
|
|
65
|
-
constructor(style) {
|
|
82
|
+
constructor(style, { dedupe = false } = {}) {
|
|
66
83
|
if (!style || !("version" in style)) {
|
|
67
84
|
throw new Error("Invalid style");
|
|
68
85
|
}
|
|
@@ -79,6 +96,7 @@ class Writer {
|
|
|
79
96
|
throw new AggregateError(errors, "Invalid style");
|
|
80
97
|
}
|
|
81
98
|
this.#style = styleCopy;
|
|
99
|
+
this.#dedupe = dedupe;
|
|
82
100
|
for (const [sourceId, source] of Object.entries(this.#style.sources)) {
|
|
83
101
|
if (source.type !== "geojson") continue;
|
|
84
102
|
this.#addSource(sourceId, source);
|
|
@@ -252,6 +270,23 @@ class Writer {
|
|
|
252
270
|
source.bounds = (0, import_geo.unionBBox)([source.bounds, bbox2]);
|
|
253
271
|
}
|
|
254
272
|
const name = (0, import_templates.getTileFilename)({ sourceId: encodedSourceId, z, x, y, format });
|
|
273
|
+
if (this.#dedupe) {
|
|
274
|
+
const data = await toUint8Array(tileData);
|
|
275
|
+
const hash = await hashData(data);
|
|
276
|
+
if (this.#addedFiles.has(name)) {
|
|
277
|
+
throw new Error(`${name} already added`);
|
|
278
|
+
}
|
|
279
|
+
this.#addedFiles.add(name);
|
|
280
|
+
const existingName = this.#tileHashes.get(hash);
|
|
281
|
+
if (existingName) {
|
|
282
|
+
this.#duplicateEntries.push({ name, originalName: existingName });
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
this.#tileHashes.set(hash, name);
|
|
286
|
+
const readable = toWebStream(data);
|
|
287
|
+
await this.#zipWriter.addEntry({ readable, name, store: true });
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
255
290
|
return this.#append(tileData, { name, store: true });
|
|
256
291
|
}
|
|
257
292
|
/**
|
|
@@ -316,7 +351,17 @@ class Writer {
|
|
|
316
351
|
this.#prepareStyle();
|
|
317
352
|
const style = JSON.stringify(this.#style);
|
|
318
353
|
await this.#append(style, { name: import_templates.STYLE_FILE });
|
|
319
|
-
|
|
354
|
+
let entries = await this.#zipWriter.entries();
|
|
355
|
+
if (this.#duplicateEntries.length > 0) {
|
|
356
|
+
const entriesByName = new Map(entries.map((e) => [e.name, e]));
|
|
357
|
+
for (const { name, originalName } of this.#duplicateEntries) {
|
|
358
|
+
const original = entriesByName.get(originalName);
|
|
359
|
+
if (!original) {
|
|
360
|
+
throw new Error(`Original entry ${originalName} not found`);
|
|
361
|
+
}
|
|
362
|
+
entries.push({ ...original, name });
|
|
363
|
+
}
|
|
364
|
+
}
|
|
320
365
|
const sortedEntries = sortEntries(entries);
|
|
321
366
|
await this.#zipWriter.finalize({ entries: sortedEntries });
|
|
322
367
|
}
|
|
@@ -430,6 +475,37 @@ function get2DBBox(bbox2) {
|
|
|
430
475
|
if (bbox2.length === 4) return bbox2;
|
|
431
476
|
return [bbox2[0], bbox2[1], bbox2[3], bbox2[4]];
|
|
432
477
|
}
|
|
478
|
+
async function toUint8Array(source) {
|
|
479
|
+
if (source instanceof Uint8Array) return source;
|
|
480
|
+
if (typeof source === "string") return new TextEncoder().encode(source);
|
|
481
|
+
const reader = (
|
|
482
|
+
/** @type {ReadableStream<Uint8Array>} */
|
|
483
|
+
source.getReader()
|
|
484
|
+
);
|
|
485
|
+
const chunks = [];
|
|
486
|
+
let totalLength = 0;
|
|
487
|
+
while (true) {
|
|
488
|
+
const { done, value } = await reader.read();
|
|
489
|
+
if (done) break;
|
|
490
|
+
chunks.push(value);
|
|
491
|
+
totalLength += value.byteLength;
|
|
492
|
+
}
|
|
493
|
+
const result = new Uint8Array(totalLength);
|
|
494
|
+
let offset = 0;
|
|
495
|
+
for (const chunk of chunks) {
|
|
496
|
+
result.set(chunk, offset);
|
|
497
|
+
offset += chunk.byteLength;
|
|
498
|
+
}
|
|
499
|
+
return result;
|
|
500
|
+
}
|
|
501
|
+
async function hashData(data) {
|
|
502
|
+
let c = globalThis.crypto;
|
|
503
|
+
if (!c) {
|
|
504
|
+
c = (await import("node:crypto")).webcrypto;
|
|
505
|
+
}
|
|
506
|
+
const buf = await c.subtle.digest("SHA-256", data);
|
|
507
|
+
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
508
|
+
}
|
|
433
509
|
function sortEntries(entries) {
|
|
434
510
|
return [...entries].sort((a, b) => {
|
|
435
511
|
if (a.name === import_templates.VERSION_FILE) return -1;
|
package/dist/writer.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { G as GlyphInfo, d as GlyphRange, e as SUPPORTED_SOURCE_TYPES, f as Source, g as SourceInfo, c as TileFormat, T as TileInfo, W as Writer } from './types-
|
|
1
|
+
export { G as GlyphInfo, d as GlyphRange, e as SUPPORTED_SOURCE_TYPES, f as Source, g as SourceInfo, c as TileFormat, T as TileInfo, W as Writer, h as WriterOptions } from './types-Bhn0-Ldk.cjs';
|
|
2
2
|
import '@maplibre/maplibre-gl-style-spec';
|
|
3
3
|
import 'geojson';
|
|
4
4
|
import 'type-fest';
|
package/dist/writer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { G as GlyphInfo, d as GlyphRange, e as SUPPORTED_SOURCE_TYPES, f as Source, g as SourceInfo, c as TileFormat, T as TileInfo, W as Writer } from './types-
|
|
1
|
+
export { G as GlyphInfo, d as GlyphRange, e as SUPPORTED_SOURCE_TYPES, f as Source, g as SourceInfo, c as TileFormat, T as TileInfo, W as Writer, h as WriterOptions } from './types-Bhn0-Ldk.js';
|
|
2
2
|
import '@maplibre/maplibre-gl-style-spec';
|
|
3
3
|
import 'geojson';
|
|
4
4
|
import 'type-fest';
|
package/dist/writer.js
CHANGED
|
@@ -44,13 +44,20 @@ class Writer {
|
|
|
44
44
|
#outputStream;
|
|
45
45
|
/** @type {ReadableStreamDefaultController<Uint8Array>} */
|
|
46
46
|
#outputController;
|
|
47
|
+
/** @type {boolean} */
|
|
48
|
+
#dedupe;
|
|
49
|
+
/** @type {Map<string, string>} hash → first entry name */
|
|
50
|
+
#tileHashes = /* @__PURE__ */ new Map();
|
|
51
|
+
/** @type {Array<{ name: string, originalName: string }>} */
|
|
52
|
+
#duplicateEntries = [];
|
|
47
53
|
static SUPPORTED_SOURCE_TYPES = SUPPORTED_SOURCE_TYPES;
|
|
48
54
|
/**
|
|
49
55
|
* @param {any} style A v7 or v8 MapLibre style. v7 styles will be migrated to
|
|
50
56
|
* v8. (There are currently no typescript declarations for v7 styles, hence
|
|
51
57
|
* this is typed as `any` and validated internally)
|
|
58
|
+
* @param {WriterOptions} [options]
|
|
52
59
|
*/
|
|
53
|
-
constructor(style) {
|
|
60
|
+
constructor(style, { dedupe = false } = {}) {
|
|
54
61
|
if (!style || !("version" in style)) {
|
|
55
62
|
throw new Error("Invalid style");
|
|
56
63
|
}
|
|
@@ -67,6 +74,7 @@ class Writer {
|
|
|
67
74
|
throw new AggregateError(errors, "Invalid style");
|
|
68
75
|
}
|
|
69
76
|
this.#style = styleCopy;
|
|
77
|
+
this.#dedupe = dedupe;
|
|
70
78
|
for (const [sourceId, source] of Object.entries(this.#style.sources)) {
|
|
71
79
|
if (source.type !== "geojson") continue;
|
|
72
80
|
this.#addSource(sourceId, source);
|
|
@@ -240,6 +248,23 @@ class Writer {
|
|
|
240
248
|
source.bounds = unionBBox([source.bounds, bbox2]);
|
|
241
249
|
}
|
|
242
250
|
const name = getTileFilename({ sourceId: encodedSourceId, z, x, y, format });
|
|
251
|
+
if (this.#dedupe) {
|
|
252
|
+
const data = await toUint8Array(tileData);
|
|
253
|
+
const hash = await hashData(data);
|
|
254
|
+
if (this.#addedFiles.has(name)) {
|
|
255
|
+
throw new Error(`${name} already added`);
|
|
256
|
+
}
|
|
257
|
+
this.#addedFiles.add(name);
|
|
258
|
+
const existingName = this.#tileHashes.get(hash);
|
|
259
|
+
if (existingName) {
|
|
260
|
+
this.#duplicateEntries.push({ name, originalName: existingName });
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
this.#tileHashes.set(hash, name);
|
|
264
|
+
const readable = toWebStream(data);
|
|
265
|
+
await this.#zipWriter.addEntry({ readable, name, store: true });
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
243
268
|
return this.#append(tileData, { name, store: true });
|
|
244
269
|
}
|
|
245
270
|
/**
|
|
@@ -304,7 +329,17 @@ class Writer {
|
|
|
304
329
|
this.#prepareStyle();
|
|
305
330
|
const style = JSON.stringify(this.#style);
|
|
306
331
|
await this.#append(style, { name: STYLE_FILE });
|
|
307
|
-
|
|
332
|
+
let entries = await this.#zipWriter.entries();
|
|
333
|
+
if (this.#duplicateEntries.length > 0) {
|
|
334
|
+
const entriesByName = new Map(entries.map((e) => [e.name, e]));
|
|
335
|
+
for (const { name, originalName } of this.#duplicateEntries) {
|
|
336
|
+
const original = entriesByName.get(originalName);
|
|
337
|
+
if (!original) {
|
|
338
|
+
throw new Error(`Original entry ${originalName} not found`);
|
|
339
|
+
}
|
|
340
|
+
entries.push({ ...original, name });
|
|
341
|
+
}
|
|
342
|
+
}
|
|
308
343
|
const sortedEntries = sortEntries(entries);
|
|
309
344
|
await this.#zipWriter.finalize({ entries: sortedEntries });
|
|
310
345
|
}
|
|
@@ -418,6 +453,37 @@ function get2DBBox(bbox2) {
|
|
|
418
453
|
if (bbox2.length === 4) return bbox2;
|
|
419
454
|
return [bbox2[0], bbox2[1], bbox2[3], bbox2[4]];
|
|
420
455
|
}
|
|
456
|
+
async function toUint8Array(source) {
|
|
457
|
+
if (source instanceof Uint8Array) return source;
|
|
458
|
+
if (typeof source === "string") return new TextEncoder().encode(source);
|
|
459
|
+
const reader = (
|
|
460
|
+
/** @type {ReadableStream<Uint8Array>} */
|
|
461
|
+
source.getReader()
|
|
462
|
+
);
|
|
463
|
+
const chunks = [];
|
|
464
|
+
let totalLength = 0;
|
|
465
|
+
while (true) {
|
|
466
|
+
const { done, value } = await reader.read();
|
|
467
|
+
if (done) break;
|
|
468
|
+
chunks.push(value);
|
|
469
|
+
totalLength += value.byteLength;
|
|
470
|
+
}
|
|
471
|
+
const result = new Uint8Array(totalLength);
|
|
472
|
+
let offset = 0;
|
|
473
|
+
for (const chunk of chunks) {
|
|
474
|
+
result.set(chunk, offset);
|
|
475
|
+
offset += chunk.byteLength;
|
|
476
|
+
}
|
|
477
|
+
return result;
|
|
478
|
+
}
|
|
479
|
+
async function hashData(data) {
|
|
480
|
+
let c = globalThis.crypto;
|
|
481
|
+
if (!c) {
|
|
482
|
+
c = (await import("node:crypto")).webcrypto;
|
|
483
|
+
}
|
|
484
|
+
const buf = await c.subtle.digest("SHA-256", data);
|
|
485
|
+
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
486
|
+
}
|
|
421
487
|
function sortEntries(entries) {
|
|
422
488
|
return [...entries].sort((a, b) => {
|
|
423
489
|
if (a.name === VERSION_FILE) return -1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "styled-map-package-api",
|
|
3
|
-
"version": "5.0.0-pre.
|
|
3
|
+
"version": "5.0.0-pre.3",
|
|
4
4
|
"description": "JavaScript API for reading, writing, and serving Styled Map Package (.smp) files",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"keywords": [],
|
|
115
115
|
"license": "MIT",
|
|
116
116
|
"dependencies": {
|
|
117
|
-
"@gmaclennan/zip-reader": "^1.0.0
|
|
117
|
+
"@gmaclennan/zip-reader": "^1.0.0",
|
|
118
118
|
"@mapbox/sphericalmercator": "^1.2.0",
|
|
119
119
|
"@maplibre/maplibre-gl-style-spec": "^20.3.1",
|
|
120
120
|
"@placemarkio/check-geojson": "^0.1.12",
|
|
@@ -124,12 +124,15 @@
|
|
|
124
124
|
"itty-router": "^5.0.22",
|
|
125
125
|
"ky": "^1.7.5",
|
|
126
126
|
"map-obj": "^5.0.2",
|
|
127
|
-
"mbtiles-reader": "^
|
|
127
|
+
"mbtiles-reader": "^2.0.1",
|
|
128
128
|
"p-limit": "^6.2.0",
|
|
129
129
|
"readable-stream": "^4.7.0",
|
|
130
130
|
"yocto-queue": "^1.1.1",
|
|
131
131
|
"zip-writer": "^2.2.0"
|
|
132
132
|
},
|
|
133
|
+
"optionalDependencies": {
|
|
134
|
+
"better-sqlite3": "^12.8.0"
|
|
135
|
+
},
|
|
133
136
|
"devDependencies": {
|
|
134
137
|
"@commander-js/extra-typings": "^12.1.0",
|
|
135
138
|
"@types/geojson": "^7946.0.16",
|