@versatiles/svelte 1.1.2 → 2.0.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.
Files changed (42) hide show
  1. package/dist/components/BasicMap/BasicMap.svelte +4 -4
  2. package/dist/components/BasicMap/BasicMap.svelte.d.ts +2 -2
  3. package/dist/components/MapEditor/MapEditor.svelte +16 -3
  4. package/dist/components/MapEditor/components/Editor.svelte +46 -40
  5. package/dist/components/MapEditor/components/Editor.svelte.d.ts +1 -1
  6. package/dist/components/MapEditor/components/EditorFill.svelte +7 -9
  7. package/dist/components/MapEditor/components/EditorStroke.svelte +9 -11
  8. package/dist/components/MapEditor/components/EditorSymbol.svelte +15 -21
  9. package/dist/components/MapEditor/components/InputRow.svelte +34 -0
  10. package/dist/components/MapEditor/components/InputRow.svelte.d.ts +9 -0
  11. package/dist/components/MapEditor/components/Sidebar.svelte +115 -108
  12. package/dist/components/MapEditor/components/SidebarPanel.svelte +92 -0
  13. package/dist/components/MapEditor/components/SidebarPanel.svelte.d.ts +10 -0
  14. package/dist/components/MapEditor/components/SymbolSelector.svelte +7 -15
  15. package/dist/components/MapEditor/lib/element/abstract.d.ts +3 -3
  16. package/dist/components/MapEditor/lib/element/abstract.js +1 -1
  17. package/dist/components/MapEditor/lib/element/line.d.ts +3 -4
  18. package/dist/components/MapEditor/lib/element/line.js +0 -1
  19. package/dist/components/MapEditor/lib/element/marker.d.ts +4 -4
  20. package/dist/components/MapEditor/lib/element/polygon.d.ts +3 -3
  21. package/dist/components/MapEditor/lib/geometry_manager.d.ts +20 -10
  22. package/dist/components/MapEditor/lib/geometry_manager.js +44 -52
  23. package/dist/components/MapEditor/lib/map_layer/abstract.d.ts +3 -2
  24. package/dist/components/MapEditor/lib/map_layer/abstract.js +3 -0
  25. package/dist/components/MapEditor/lib/map_layer/fill.d.ts +4 -3
  26. package/dist/components/MapEditor/lib/map_layer/fill.js +9 -8
  27. package/dist/components/MapEditor/lib/map_layer/line.d.ts +4 -3
  28. package/dist/components/MapEditor/lib/map_layer/line.js +15 -14
  29. package/dist/components/MapEditor/lib/map_layer/symbol.d.ts +5 -4
  30. package/dist/components/MapEditor/lib/map_layer/symbol.js +28 -46
  31. package/dist/components/MapEditor/lib/state/constants.d.ts +4 -0
  32. package/dist/components/MapEditor/lib/state/constants.js +22 -0
  33. package/dist/components/MapEditor/lib/state/manager.d.ts +16 -0
  34. package/dist/components/MapEditor/lib/state/manager.js +76 -0
  35. package/dist/components/MapEditor/lib/state/reader.d.ts +21 -14
  36. package/dist/components/MapEditor/lib/state/reader.js +259 -142
  37. package/dist/components/MapEditor/lib/state/types.d.ts +27 -12
  38. package/dist/components/MapEditor/lib/state/writer.d.ts +18 -14
  39. package/dist/components/MapEditor/lib/state/writer.js +182 -169
  40. package/dist/components/MapEditor/lib/utils.d.ts +2 -5
  41. package/dist/components/MapEditor/lib/utils.js +0 -19
  42. package/package.json +19 -19
@@ -1,192 +1,205 @@
1
1
  import { Color } from '@versatiles/style';
2
- import { compress, uint8ArrayToBase64 } from '../utils.js';
3
- const chunkSize = 65536;
2
+ import { BASE64_CHARS, CHAR_CODE2VALUE } from './constants.js';
3
+ import { StateReader } from './reader.js';
4
4
  export class StateWriter {
5
- buffer = new Uint8Array(chunkSize);
6
- offset = 0;
5
+ bits = [];
7
6
  constructor() { }
8
- writeByte(num) {
9
- if (this.offset >= this.buffer.length) {
10
- const newBuffer = new Uint8Array(this.buffer.length + chunkSize);
11
- newBuffer.set(this.buffer);
12
- this.buffer = newBuffer;
7
+ asBase64() {
8
+ const reader = new StateReader(this.bits);
9
+ const chars = [];
10
+ while (!reader.ended()) {
11
+ chars.push(BASE64_CHARS[reader.read6pack()]);
13
12
  }
14
- this.buffer[this.offset++] = num;
13
+ return chars.join('');
15
14
  }
16
- writeUnsignedInteger(i) {
17
- if (!Number.isSafeInteger(i)) {
18
- throw new RangeError(`Number out of safe integer range: ${i}`);
19
- }
20
- while (i > 0x7f) {
21
- this.writeByte((i & 0x7f) | 0x80);
22
- i >>>= 7;
15
+ asBitString() {
16
+ return this.bits.map((bit) => (bit ? '1' : '0')).join('');
17
+ }
18
+ writeBit(value) {
19
+ this.bits.push(value);
20
+ }
21
+ writeInteger(value, bits) {
22
+ if (value % 1 !== 0)
23
+ throw new Error('value must be an integer');
24
+ for (let i = bits - 1; i >= 0; i--) {
25
+ this.bits.push((value & (1 << i)) > 0);
23
26
  }
24
- this.writeByte(i);
27
+ return value;
25
28
  }
26
- writeSignedInteger(i) {
27
- if (!Number.isSafeInteger(i)) {
28
- throw new RangeError(`Number out of safe integer range: ${i}`);
29
+ writeVarint(value, signed) {
30
+ if (value % 1 !== 0)
31
+ throw new Error('value must be an integer');
32
+ if (signed) {
33
+ value = value < 0 ? ((-1 - value) << 1) | 1 : value << 1;
34
+ }
35
+ else {
36
+ if (value < 0)
37
+ throw new Error('Unsigned varint cannot be negative');
38
+ }
39
+ while (true) {
40
+ this.writeInteger(value & 0x1f, 5);
41
+ value >>= 5;
42
+ this.writeBit(value >= 1);
43
+ if (value < 1)
44
+ break;
29
45
  }
30
- this.writeUnsignedInteger(i < 0 ? -i * 2 - 1 : i * 2);
31
46
  }
32
- writeString(str) {
33
- const length = str.length;
34
- this.writeUnsignedInteger(length);
47
+ writeArray(array, cb) {
48
+ const length = array.length;
49
+ this.writeVarint(length);
35
50
  for (let i = 0; i < length; i++)
36
- this.writeUnsignedInteger(str.charCodeAt(i));
37
- }
38
- writeBoolean(b) {
39
- this.writeByte(b ? 1 : 0);
51
+ cb(array[i]);
40
52
  }
41
- getBase64() {
42
- return uint8ArrayToBase64(this.getBuffer());
53
+ writePoint(point, level = 14) {
54
+ const scale = Math.pow(2, level + 2);
55
+ this.writeInteger(Math.round(point[0] * scale), level + 11);
56
+ this.writeInteger(Math.round(point[1] * scale), level + 10);
43
57
  }
44
- async getBase64compressed() {
45
- return uint8ArrayToBase64(await compress(this.getBuffer()));
46
- }
47
- getBuffer() {
48
- return this.buffer.slice(0, this.offset);
58
+ writePoints(points, level = 14) {
59
+ this.writeVarint(points.length);
60
+ const scale = Math.pow(2, level + 2);
61
+ let x = 0;
62
+ let y = 0;
63
+ points.forEach((point) => {
64
+ const xi = Math.round(point[0] * scale);
65
+ const yi = Math.round(point[1] * scale);
66
+ this.writeVarint(xi - x, true);
67
+ this.writeVarint(yi - y, true);
68
+ x = xi;
69
+ y = yi;
70
+ });
49
71
  }
50
- writeObject(state) {
51
- // eslint-disable-next-line @typescript-eslint/no-this-alias
52
- const me = this;
53
- Object.entries(state).forEach(([key, value]) => {
54
- if (value == null)
55
- return;
56
- switch (key) {
57
- case 'map':
58
- writeObject(10, value);
59
- break;
60
- case 'style':
61
- writeObject(11, value);
62
- break;
63
- case 'strokeStyle':
64
- writeObject(12, value);
65
- break;
66
- case 'elements':
67
- if (!Array.isArray(value))
68
- throw new Error(`Invalid elements: ${value}`);
69
- if (value.length === 0)
70
- return;
71
- this.writeByte(20);
72
- this.writeUnsignedInteger(value.length);
73
- value.forEach((element) => this.writeObject(element));
74
- break;
75
- case 'point':
76
- if (!Array.isArray(value) || value.length !== 2)
77
- throw new Error(`Invalid point: ${value}`);
78
- this.writeByte(30);
79
- me.writeSignedInteger(Math.round(value[0] * 1e5));
80
- me.writeSignedInteger(Math.round(value[1] * 1e5));
81
- break;
82
- case 'points':
83
- if (!Array.isArray(value))
84
- throw new Error(`Invalid points: ${value}`);
85
- if (value.length === 0)
86
- return;
87
- this.writeByte(31);
88
- this.writeUnsignedInteger(value.length);
89
- this.writeDifferential(value.map((p) => Math.round(p[0] * 1e5)));
90
- this.writeDifferential(value.map((p) => Math.round(p[1] * 1e5)));
91
- break;
92
- case 'color':
93
- this.writeByte(40);
94
- this.writeColor(value);
95
- break;
96
- case 'type':
97
- this.writeByte(50);
98
- switch (value) {
99
- case 'marker':
100
- this.writeByte(0);
101
- break;
102
- case 'line':
103
- this.writeByte(1);
104
- break;
105
- case 'polygon':
106
- this.writeByte(2);
107
- break;
108
- default:
109
- throw new Error(`Invalid type: ${value}`);
110
- }
111
- break;
112
- case 'label':
113
- if (typeof value !== 'string')
114
- throw new Error(`Invalid string: ${value}`);
115
- this.writeByte(60);
116
- this.writeString(value);
117
- break;
118
- case 'halo':
119
- writeInteger(70, value, 10);
120
- break;
121
- case 'opacity':
122
- writeInteger(71, value, 100);
123
- break;
124
- case 'pattern':
125
- writeInteger(72, value);
126
- break;
127
- case 'rotate':
128
- writeSignedInteger(73, value);
129
- break;
130
- case 'size':
131
- writeInteger(74, value, 10);
132
- break;
133
- case 'width':
134
- writeInteger(75, value, 10);
135
- break;
136
- case 'zoom':
137
- writeInteger(76, value, 20);
138
- break;
139
- case 'align':
140
- writeInteger(77, value);
141
- break;
142
- case 'visible':
143
- if (typeof value !== 'boolean')
144
- throw new Error(`Invalid boolean: ${value}`);
145
- this.writeByte(90);
146
- this.writeBoolean(value);
72
+ writeRoot(root) {
73
+ // Write the version
74
+ this.writeInteger(0, 3);
75
+ if (root.map) {
76
+ this.writeBit(true);
77
+ this.writeMap(root.map);
78
+ }
79
+ else {
80
+ this.writeBit(false);
81
+ }
82
+ // metadata is not used yet
83
+ this.writeBit(false);
84
+ root.elements.forEach((element) => {
85
+ switch (element.type) {
86
+ case 'marker':
87
+ this.writeInteger(1, 3);
88
+ this.writeElementMarker(element);
89
+ break;
90
+ case 'line':
91
+ this.writeInteger(2, 3);
92
+ this.writeElementLine(element);
93
+ break;
94
+ case 'polygon':
95
+ this.writeInteger(3, 3);
96
+ this.writeElementPolygon(element);
147
97
  break;
148
- default:
149
- throw new Error(`Invalid state key: ${key}`);
150
98
  }
151
99
  });
152
- this.writeByte(0);
153
- function writeObject(id, obj) {
154
- if (typeof obj !== 'object' || obj == null)
155
- throw new Error(`Invalid object: ${obj}`);
156
- me.writeByte(id);
157
- me.writeObject(obj);
158
- }
159
- function writeInteger(id, obj, factor = 1) {
160
- if (typeof obj !== 'number')
161
- throw new Error(`Invalid number: ${obj}`);
162
- const value = Math.round(obj);
163
- if (value < 0)
164
- throw new Error(`Negative Number: ${obj}`);
165
- me.writeByte(id);
166
- me.writeUnsignedInteger(value * factor);
100
+ }
101
+ writeMap(map) {
102
+ this.writeInteger(Math.round(map.zoom * 32), 10);
103
+ this.writePoint(map.center, Math.ceil(map.zoom));
104
+ }
105
+ writeElementMarker(element) {
106
+ this.writePoint(element.point);
107
+ if (element.style) {
108
+ this.writeBit(true);
109
+ this.writeStyle(element.style);
110
+ }
111
+ else {
112
+ this.writeBit(false);
113
+ }
114
+ return element;
115
+ }
116
+ writeElementLine(element) {
117
+ this.writePoints(element.points);
118
+ if (element.style) {
119
+ this.writeBit(true);
120
+ this.writeStyle(element.style);
121
+ }
122
+ else {
123
+ this.writeBit(false);
124
+ }
125
+ return element;
126
+ }
127
+ writeElementPolygon(element) {
128
+ this.writePoints(element.points);
129
+ if (element.style) {
130
+ this.writeBit(true);
131
+ this.writeStyle(element.style);
132
+ }
133
+ else {
134
+ this.writeBit(false);
135
+ }
136
+ if (element.strokeStyle) {
137
+ this.writeBit(true);
138
+ this.writeStyle(element.strokeStyle);
167
139
  }
168
- function writeSignedInteger(id, obj, factor = 1) {
169
- if (typeof obj !== 'number')
170
- throw new Error(`Invalid number: ${obj}`);
171
- const value = Math.round(obj);
172
- me.writeByte(id);
173
- me.writeSignedInteger(value * factor);
140
+ else {
141
+ this.writeBit(false);
174
142
  }
175
143
  }
144
+ writeStyle(style) {
145
+ if (style.halo != null) {
146
+ this.writeInteger(1, 4);
147
+ this.writeVarint(Math.round(style.halo * 10));
148
+ }
149
+ if (style.opacity != null) {
150
+ this.writeInteger(2, 4);
151
+ this.writeVarint(Math.round(style.opacity * 100));
152
+ }
153
+ if (style.pattern != null) {
154
+ this.writeInteger(3, 4);
155
+ this.writeVarint(style.pattern);
156
+ }
157
+ if (style.rotate != null) {
158
+ this.writeInteger(4, 4);
159
+ this.writeVarint(style.rotate, true);
160
+ }
161
+ if (style.size != null) {
162
+ this.writeInteger(5, 4);
163
+ this.writeVarint(Math.round(style.size * 10));
164
+ }
165
+ if (style.width != null) {
166
+ this.writeInteger(6, 4);
167
+ this.writeVarint(Math.round(style.width * 10));
168
+ }
169
+ if (style.align != null) {
170
+ this.writeInteger(7, 4);
171
+ this.writeVarint(style.align);
172
+ }
173
+ if (style.color != null) {
174
+ this.writeInteger(8, 4);
175
+ this.writeColor(style.color);
176
+ }
177
+ if (style.label != null) {
178
+ this.writeInteger(9, 4);
179
+ this.writeString(style.label);
180
+ }
181
+ if (style.visible === false) {
182
+ this.writeInteger(10, 4);
183
+ }
184
+ this.writeInteger(0, 4);
185
+ }
176
186
  writeColor(color) {
177
- if (typeof color !== 'string')
178
- throw new Error(`Invalid color: ${color}`);
179
- const c = Color.parse(color).asRGB().round().asArray();
180
- this.writeByte(c[0]);
181
- this.writeByte(c[1]);
182
- this.writeByte(c[2]);
183
- }
184
- writeDifferential(values) {
185
- if (values.length === 0)
186
- return;
187
- this.writeSignedInteger(values[0]);
188
- for (let i = 1; i < values.length; i++) {
189
- this.writeSignedInteger(values[i] - values[i - 1]);
187
+ const rgb = Color.parse(color).toRGB();
188
+ this.writeInteger(rgb.r, 8);
189
+ this.writeInteger(rgb.g, 8);
190
+ this.writeInteger(rgb.b, 8);
191
+ if (rgb.a == 1) {
192
+ this.bits.push(false);
193
+ }
194
+ else {
195
+ this.bits.push(true);
196
+ this.writeInteger(Math.round(rgb.a * 255), 8);
190
197
  }
191
198
  }
199
+ writeString(value) {
200
+ const charCodes = value.split('').map((c) => c.charCodeAt(0));
201
+ this.writeVarint(charCodes.length);
202
+ charCodes.forEach((c) => this.writeVarint(c < 128 ? CHAR_CODE2VALUE[c] : c));
203
+ return value;
204
+ }
192
205
  }
@@ -1,9 +1,6 @@
1
1
  import type { ElementPoint } from './element/types.js';
2
+ import type { StateStyle } from './state/types.js';
2
3
  export declare function getMiddlePoint(p0: ElementPoint, p1: ElementPoint): ElementPoint;
3
4
  export declare function lat2mercator(lat: number): number;
4
5
  export declare function mercator2lat(y: number): number;
5
- export declare function base64ToUint8Array(base64: string): Uint8Array;
6
- export declare function uint8ArrayToBase64(data: Uint8Array): string;
7
- export declare function compress(data: Uint8Array): Promise<Uint8Array>;
8
- export declare function decompress(data: Uint8Array): Promise<Uint8Array>;
9
- export declare function removeDefaultFields<T extends Record<string, unknown>>(value: T, def: T): Partial<T> | undefined;
6
+ export declare function removeDefaultFields(value: StateStyle, def: StateStyle): Partial<StateStyle> | undefined;
@@ -9,25 +9,6 @@ export function lat2mercator(lat) {
9
9
  export function mercator2lat(y) {
10
10
  return ((2 * Math.atan(Math.exp(y)) - Math.PI / 2) * 180) / Math.PI;
11
11
  }
12
- export function base64ToUint8Array(base64) {
13
- const binaryString = atob(base64);
14
- return Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
15
- }
16
- export function uint8ArrayToBase64(data) {
17
- const binaryString = String.fromCharCode(...data);
18
- return btoa(binaryString);
19
- }
20
- export async function compress(data) {
21
- const stream = new Blob([data]).stream();
22
- const compressedStream = stream.pipeThrough(new CompressionStream('deflate-raw'));
23
- return new Uint8Array(await new Response(compressedStream).arrayBuffer());
24
- }
25
- export async function decompress(data) {
26
- const stream = new Blob([data]).stream();
27
- const decompressedStream = stream.pipeThrough(new DecompressionStream('deflate-raw'));
28
- const arrayBuffer = await new Response(decompressedStream).arrayBuffer();
29
- return new Uint8Array(arrayBuffer);
30
- }
31
12
  export function removeDefaultFields(value, def) {
32
13
  const entries = Object.entries(value).filter(([k, v]) => {
33
14
  if (v === undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versatiles/svelte",
3
- "version": "1.1.2",
3
+ "version": "2.0.0",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "build": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && vite build && npm run package",
@@ -36,45 +36,45 @@
36
36
  "!dist/BBoxMap/helpers/*"
37
37
  ],
38
38
  "peerDependencies": {
39
- "sass-embedded": "^1.86.0",
40
- "svelte": "^5.23.2"
39
+ "sass-embedded": "^1.86.3",
40
+ "svelte": "^5.27.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@playwright/test": "^1.51.1",
44
44
  "@sveltejs/adapter-static": "^3.0.8",
45
- "@sveltejs/kit": "^2.20.1",
46
- "@sveltejs/package": "^2.3.10",
45
+ "@sveltejs/kit": "^2.20.7",
46
+ "@sveltejs/package": "^2.3.11",
47
47
  "@sveltejs/vite-plugin-svelte": "^5.0.3",
48
48
  "@turf/turf": "^7.2.0",
49
49
  "@types/eslint": "^9.6.1",
50
- "@types/node": "^22.13.10",
50
+ "@types/node": "^22.14.1",
51
51
  "@versatiles/release-tool": "^2.4.2",
52
- "@vitest/coverage-v8": "^3.0.9",
52
+ "@vitest/coverage-v8": "^3.1.1",
53
53
  "cookie": "^1.0.2",
54
- "eslint": "^9.22.0",
55
- "eslint-config-prettier": "^10.1.1",
56
- "eslint-plugin-svelte": "^3.3.2",
54
+ "eslint": "^9.24.0",
55
+ "eslint-config-prettier": "^10.1.2",
56
+ "eslint-plugin-svelte": "^3.5.1",
57
57
  "geojson": "^0.5.0",
58
58
  "globals": "^16.0.0",
59
59
  "happy-dom": "^17.4.4",
60
60
  "prettier": "^3.5.3",
61
61
  "prettier-plugin-svelte": "^3.3.3",
62
- "publint": "^0.3.9",
63
- "sass": "^1.86.0",
64
- "svelte": "^5.23.2",
65
- "svelte-check": "^4.1.5",
62
+ "publint": "^0.3.12",
63
+ "sass": "^1.86.3",
64
+ "svelte": "^5.27.0",
65
+ "svelte-check": "^4.1.6",
66
66
  "svelte-preprocess": "^6.0.3",
67
67
  "tsx": "^4.19.3",
68
- "typescript": "^5.8.2",
69
- "typescript-eslint": "^8.26.1",
70
- "vite": "^6.2.2",
71
- "vitest": "^3.0.9"
68
+ "typescript": "^5.8.3",
69
+ "typescript-eslint": "^8.30.1",
70
+ "vite": "^6.2.6",
71
+ "vitest": "^3.1.1"
72
72
  },
73
73
  "svelte": "./dist/index.js",
74
74
  "types": "./dist/index.d.ts",
75
75
  "type": "module",
76
76
  "dependencies": {
77
77
  "@versatiles/style": "^5.6.0",
78
- "maplibre-gl": "^5.2.0"
78
+ "maplibre-gl": "^5.3.1"
79
79
  }
80
80
  }