@osmix/shared 0.0.1 → 0.0.6

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 (125) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +49 -19
  3. package/dist/src/assert.d.ts +24 -0
  4. package/dist/src/assert.d.ts.map +1 -0
  5. package/dist/src/assert.js +28 -0
  6. package/dist/src/assert.js.map +1 -0
  7. package/dist/src/bbox-intersects.d.ts +15 -0
  8. package/dist/src/bbox-intersects.d.ts.map +1 -0
  9. package/dist/src/bbox-intersects.js +24 -0
  10. package/dist/src/bbox-intersects.js.map +1 -0
  11. package/dist/src/bytes-to-stream.d.ts +18 -0
  12. package/dist/src/bytes-to-stream.d.ts.map +1 -0
  13. package/dist/src/bytes-to-stream.js +25 -0
  14. package/dist/src/bytes-to-stream.js.map +1 -0
  15. package/dist/src/concat-bytes.d.ts +5 -0
  16. package/dist/src/concat-bytes.d.ts.map +1 -0
  17. package/dist/src/concat-bytes.js +14 -0
  18. package/dist/src/concat-bytes.js.map +1 -0
  19. package/dist/src/coordinates.d.ts +28 -0
  20. package/dist/src/coordinates.d.ts.map +1 -0
  21. package/dist/src/coordinates.js +38 -0
  22. package/dist/src/coordinates.js.map +1 -0
  23. package/dist/src/haversine-distance.d.ts +16 -0
  24. package/dist/src/haversine-distance.d.ts.map +1 -0
  25. package/dist/src/haversine-distance.js +26 -0
  26. package/dist/src/haversine-distance.js.map +1 -0
  27. package/dist/src/lineclip.d.ts +2 -0
  28. package/dist/src/lineclip.d.ts.map +1 -0
  29. package/dist/src/lineclip.js +3 -0
  30. package/dist/src/lineclip.js.map +1 -0
  31. package/dist/src/progress.d.ts +40 -0
  32. package/dist/src/progress.d.ts.map +1 -0
  33. package/dist/src/progress.js +40 -0
  34. package/dist/src/progress.js.map +1 -0
  35. package/dist/src/relation-kind.d.ts +69 -0
  36. package/dist/src/relation-kind.d.ts.map +1 -0
  37. package/dist/src/relation-kind.js +375 -0
  38. package/dist/src/relation-kind.js.map +1 -0
  39. package/dist/src/relation-multipolygon.d.ts +43 -0
  40. package/dist/src/relation-multipolygon.d.ts.map +1 -0
  41. package/dist/src/relation-multipolygon.js +195 -0
  42. package/dist/src/relation-multipolygon.js.map +1 -0
  43. package/dist/src/stream-to-bytes.d.ts +18 -0
  44. package/dist/src/stream-to-bytes.d.ts.map +1 -0
  45. package/dist/src/stream-to-bytes.js +30 -0
  46. package/dist/src/stream-to-bytes.js.map +1 -0
  47. package/dist/src/test/fixtures.d.ts +36 -0
  48. package/dist/src/test/fixtures.d.ts.map +1 -0
  49. package/dist/src/test/fixtures.js +172 -0
  50. package/dist/src/test/fixtures.js.map +1 -0
  51. package/dist/src/throttle.d.ts +25 -0
  52. package/dist/src/throttle.d.ts.map +1 -0
  53. package/dist/src/throttle.js +34 -0
  54. package/dist/src/throttle.js.map +1 -0
  55. package/dist/src/tile.d.ts +34 -0
  56. package/dist/src/tile.d.ts.map +1 -0
  57. package/dist/src/tile.js +72 -0
  58. package/dist/src/tile.js.map +1 -0
  59. package/dist/src/transform-bytes.d.ts +24 -0
  60. package/dist/src/transform-bytes.d.ts.map +1 -0
  61. package/dist/src/transform-bytes.js +28 -0
  62. package/dist/src/transform-bytes.js.map +1 -0
  63. package/dist/src/types.d.ts +99 -0
  64. package/dist/src/types.d.ts.map +1 -0
  65. package/dist/src/types.js +9 -0
  66. package/dist/src/types.js.map +1 -0
  67. package/dist/src/utils.d.ts +30 -0
  68. package/dist/src/utils.d.ts.map +1 -0
  69. package/dist/src/utils.js +70 -0
  70. package/dist/src/utils.js.map +1 -0
  71. package/dist/src/way-is-area.d.ts +24 -0
  72. package/dist/src/way-is-area.d.ts.map +1 -0
  73. package/dist/src/way-is-area.js +104 -0
  74. package/dist/src/way-is-area.js.map +1 -0
  75. package/dist/src/zigzag.d.ts +33 -0
  76. package/dist/src/zigzag.d.ts.map +1 -0
  77. package/dist/src/zigzag.js +40 -0
  78. package/dist/src/zigzag.js.map +1 -0
  79. package/dist/test/haversine-distance.test.d.ts +2 -0
  80. package/dist/test/haversine-distance.test.d.ts.map +1 -0
  81. package/dist/test/haversine-distance.test.js +8 -0
  82. package/dist/test/haversine-distance.test.js.map +1 -0
  83. package/dist/test/relation-kind.test.d.ts +2 -0
  84. package/dist/test/relation-kind.test.d.ts.map +1 -0
  85. package/dist/test/relation-kind.test.js +367 -0
  86. package/dist/test/relation-kind.test.js.map +1 -0
  87. package/dist/test/relation-multipolygon.test.d.ts +2 -0
  88. package/dist/test/relation-multipolygon.test.d.ts.map +1 -0
  89. package/dist/test/relation-multipolygon.test.js +237 -0
  90. package/dist/test/relation-multipolygon.test.js.map +1 -0
  91. package/dist/test/utils.test.d.ts +2 -0
  92. package/dist/test/utils.test.d.ts.map +1 -0
  93. package/dist/test/utils.test.js +76 -0
  94. package/dist/test/utils.test.js.map +1 -0
  95. package/dist/test/way-is-area.test.d.ts +2 -0
  96. package/dist/test/way-is-area.test.d.ts.map +1 -0
  97. package/dist/test/way-is-area.test.js +31 -0
  98. package/dist/test/way-is-area.test.js.map +1 -0
  99. package/package.json +9 -7
  100. package/src/assert.ts +21 -1
  101. package/src/bbox-intersects.ts +30 -0
  102. package/src/bytes-to-stream.ts +17 -0
  103. package/src/coordinates.ts +45 -0
  104. package/src/haversine-distance.ts +10 -1
  105. package/src/progress.ts +55 -0
  106. package/src/relation-kind.ts +446 -0
  107. package/src/relation-multipolygon.ts +225 -0
  108. package/src/stream-to-bytes.ts +17 -0
  109. package/src/test/fixtures.ts +18 -14
  110. package/src/throttle.ts +37 -0
  111. package/src/tile.ts +89 -0
  112. package/src/transform-bytes.ts +23 -0
  113. package/src/types.ts +93 -1
  114. package/src/utils.ts +79 -0
  115. package/src/way-is-area.ts +107 -0
  116. package/src/zigzag.ts +42 -0
  117. package/test/haversine-distance.test.ts +2 -2
  118. package/test/relation-kind.test.ts +426 -0
  119. package/test/relation-multipolygon.test.ts +265 -0
  120. package/test/utils.test.ts +103 -0
  121. package/test/way-is-area.test.ts +42 -0
  122. package/tsconfig/base.json +2 -0
  123. package/tsconfig/test.json +1 -0
  124. package/src/spherical-mercator.test.ts +0 -42
  125. package/src/spherical-mercator.ts +0 -42
@@ -0,0 +1,76 @@
1
+ import { describe, expect, it } from "bun:test";
2
+ import { entityPropertiesEqual, getEntityType, isMultipolygonRelation, isNode, isNodeEqual, isRelation, isRelationEqual, isWay, isWayEqual, } from "../src/utils";
3
+ describe("utils", () => {
4
+ const node = {
5
+ id: 1,
6
+ lat: 10,
7
+ lon: 20,
8
+ tags: { name: "node" },
9
+ };
10
+ const way = {
11
+ id: 2,
12
+ refs: [1, 2, 3],
13
+ tags: { highway: "residential" },
14
+ };
15
+ const members = [
16
+ {
17
+ type: "node",
18
+ ref: 1,
19
+ },
20
+ ];
21
+ const relation = {
22
+ id: 3,
23
+ members,
24
+ tags: { type: "multipolygon" },
25
+ };
26
+ it("narrows entity types", () => {
27
+ expect(isNode(node)).toBe(true);
28
+ expect(isWay(way)).toBe(true);
29
+ expect(isRelation(relation)).toBe(true);
30
+ });
31
+ it("compares entity equality", () => {
32
+ expect(isNodeEqual(node, { ...node })).toBe(true);
33
+ expect(isWayEqual(way, { ...way })).toBe(true);
34
+ expect(isRelationEqual(relation, { ...relation })).toBe(true);
35
+ });
36
+ it("detects property differences", () => {
37
+ expect(entityPropertiesEqual(node, { ...node, tags: { name: "changed" } })).toBe(false);
38
+ expect(entityPropertiesEqual(way, { ...way, refs: [1, 2, 4] })).toBe(false);
39
+ expect(entityPropertiesEqual(relation, {
40
+ ...relation,
41
+ members: [{ type: "node", ref: 2 }],
42
+ })).toBe(false);
43
+ });
44
+ it("provides entity type", () => {
45
+ expect(getEntityType(node)).toBe("node");
46
+ expect(getEntityType(way)).toBe("way");
47
+ expect(getEntityType(relation)).toBe("relation");
48
+ });
49
+ describe("isMultipolygonRelation", () => {
50
+ it("identifies multipolygon relations", () => {
51
+ const relation = {
52
+ id: 1,
53
+ tags: { type: "multipolygon" },
54
+ members: [],
55
+ };
56
+ expect(isMultipolygonRelation(relation)).toBe(true);
57
+ });
58
+ it("rejects non-multipolygon relations", () => {
59
+ const relation = {
60
+ id: 1,
61
+ tags: { type: "route" },
62
+ members: [],
63
+ };
64
+ expect(isMultipolygonRelation(relation)).toBe(false);
65
+ });
66
+ it("rejects relations without type tag", () => {
67
+ const relation = {
68
+ id: 1,
69
+ tags: { name: "test" },
70
+ members: [],
71
+ };
72
+ expect(isMultipolygonRelation(relation)).toBe(false);
73
+ });
74
+ });
75
+ });
76
+ //# sourceMappingURL=utils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../test/utils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=way-is-area.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"way-is-area.test.d.ts","sourceRoot":"","sources":["../../test/way-is-area.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import { describe, expect, it } from "bun:test";
2
+ import { wayIsArea } from "../src/way-is-area";
3
+ describe("wayIsArea", () => {
4
+ it("returns false for open ways", () => {
5
+ const refs = [1, 2, 3];
6
+ expect(wayIsArea({ id: 0, refs, tags: { building: "yes" } })).toBe(false);
7
+ });
8
+ it("returns true for closed way without tags", () => {
9
+ const refs = [1, 2, 3, 1];
10
+ expect(wayIsArea({ id: 0, refs })).toBe(true);
11
+ });
12
+ it("honors explicit area override", () => {
13
+ const refs = [1, 2, 3, 1];
14
+ expect(wayIsArea({ id: 0, refs, tags: { area: "no", building: "yes" } })).toBe(false);
15
+ expect(wayIsArea({ id: 0, refs, tags: { area: "yes" } })).toBe(true);
16
+ });
17
+ it("treats implied tags as areas", () => {
18
+ const refs = [1, 2, 3, 1];
19
+ expect(wayIsArea({ id: 0, refs, tags: { building: "yes" } })).toBe(true);
20
+ });
21
+ it("considers included values", () => {
22
+ const refs = [1, 2, 3, 1];
23
+ expect(wayIsArea({ id: 0, refs, tags: { highway: "rest_area" } })).toBe(true);
24
+ expect(wayIsArea({ id: 0, refs, tags: { highway: "primary" } })).toBe(false);
25
+ });
26
+ it("rejects excluded values", () => {
27
+ const refs = [1, 2, 3, 1];
28
+ expect(wayIsArea({ id: 0, refs, tags: { natural: "coastline" } })).toBe(false);
29
+ });
30
+ });
31
+ //# sourceMappingURL=way-is-area.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"way-is-area.test.js","sourceRoot":"","sources":["../../test/way-is-area.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@osmix/shared",
4
4
  "type": "module",
5
- "version": "0.0.1",
5
+ "version": "0.0.6",
6
6
  "description": "Shared utilities for Osmix",
7
7
  "exports": {
8
8
  "./*": "./src/*.ts",
@@ -37,16 +37,18 @@
37
37
  "sideEffects": false,
38
38
  "scripts": {
39
39
  "build": "tsc",
40
- "bench": "vitest bench",
41
- "test": "vitest",
42
- "typecheck": "tsc --noEmit"
40
+ "bench": "bun test --bench",
41
+ "prepublishOnly": "tsc",
42
+ "test": "bun test",
43
+ "typecheck": "tsgo --noEmit"
43
44
  },
44
45
  "devDependencies": {
45
- "typescript": "catalog:",
46
- "vitest": "catalog:"
46
+ "@types/bun": "catalog:",
47
+ "typescript": "catalog:"
47
48
  },
48
49
  "dependencies": {
49
- "@mapbox/sphericalmercator": "catalog:",
50
+ "@mapbox/tilebelt": "^2.0.2",
51
+ "dequal": "catalog:",
50
52
  "lineclip": "^2.0.0"
51
53
  }
52
54
  }
package/src/assert.ts CHANGED
@@ -1,5 +1,25 @@
1
1
  /**
2
- * Short utility for checking index access.
2
+ * Assertion utilities for defensive programming.
3
+ *
4
+ * Provides typed assertion helpers that throw errors when conditions are not met,
5
+ * commonly used for index bounds checking and null/undefined guards.
6
+ *
7
+ * @module
8
+ */
9
+
10
+ /**
11
+ * Assert that a value is neither null nor undefined.
12
+ *
13
+ * @param value - The value to check.
14
+ * @param message - Optional error message if assertion fails.
15
+ * @throws Error if value is null or undefined.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * const item = array[index]
20
+ * assertValue(item, `No item at index ${index}`)
21
+ * // TypeScript now knows item is non-nullable
22
+ * ```
3
23
  */
4
24
  export function assertValue<T>(
5
25
  value?: T,
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Bounding box intersection and containment utilities.
3
+ *
4
+ * Provides functions for checking spatial relationships between
5
+ * geographic bounding boxes (west, south, east, north format).
6
+ *
7
+ * @module
8
+ */
9
+
10
+ import type { GeoBbox2D } from "./types"
11
+
12
+ /**
13
+ * Check if two bounding boxes intersect or contain each other.
14
+ * Handles both partial overlaps and complete containment.
15
+ */
16
+ export function bboxContainsOrIntersects(bb1: GeoBbox2D, bb2: GeoBbox2D) {
17
+ const westIn =
18
+ (bb1[0] >= bb2[0] && bb1[0] <= bb2[2]) ||
19
+ (bb2[0] >= bb1[0] && bb2[0] <= bb1[2])
20
+ const eastIn =
21
+ (bb1[2] >= bb2[0] && bb1[2] <= bb2[2]) ||
22
+ (bb2[2] >= bb1[0] && bb2[2] <= bb1[2])
23
+ const northIn =
24
+ (bb1[1] >= bb2[1] && bb1[1] <= bb2[3]) ||
25
+ (bb2[1] >= bb1[1] && bb2[1] <= bb1[3])
26
+ const southIn =
27
+ (bb1[3] >= bb2[1] && bb1[3] <= bb2[3]) ||
28
+ (bb2[3] >= bb1[1] && bb2[3] <= bb1[3])
29
+ return (westIn || eastIn) && (northIn || southIn)
30
+ }
@@ -1,3 +1,20 @@
1
+ /**
2
+ * Byte array to stream conversion.
3
+ *
4
+ * Wraps a Uint8Array in a ReadableStream for use with streaming APIs.
5
+ *
6
+ * @module
7
+ */
8
+
9
+ /**
10
+ * Create a ReadableStream from a Uint8Array.
11
+ *
12
+ * The stream will emit the entire byte array as a single chunk,
13
+ * then close immediately.
14
+ *
15
+ * @param bytes - The byte array to wrap.
16
+ * @returns A ReadableStream that emits the bytes.
17
+ */
1
18
  export function bytesToStream(bytes: Uint8Array<ArrayBuffer>) {
2
19
  return new ReadableStream<Uint8Array<ArrayBuffer>>({
3
20
  start(controller) {
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Coordinate precision utilities for OSM data.
3
+ *
4
+ * OSM stores coordinates as integer microdegrees (7 decimal places) for
5
+ * compact storage and consistent precision. This module provides conversions
6
+ * between floating-point degrees and integer microdegrees.
7
+ *
8
+ * @module
9
+ */
10
+
11
+ import type { GeoBbox2D } from "./types"
12
+
13
+ /**
14
+ * OSM coordinate scale: coordinates are stored as integer microdegrees.
15
+ * 1 microdegree = 1e-7 degrees = 0.0000001 degrees
16
+ */
17
+ export const OSM_COORD_SCALE = 1e7
18
+
19
+ /**
20
+ * Convert degrees to microdegrees (integer).
21
+ */
22
+ export function toMicroDegrees(degrees: number): number {
23
+ return Math.round(degrees * OSM_COORD_SCALE)
24
+ }
25
+
26
+ /**
27
+ * Convert microdegrees (integer) to degrees (float).
28
+ */
29
+ export function microToDegrees(microdegrees: number): number {
30
+ return microdegrees / OSM_COORD_SCALE
31
+ }
32
+
33
+ /**
34
+ * Convert a bounding box from degrees to microdegrees.
35
+ */
36
+ export function bboxToMicroDegrees(
37
+ bbox: GeoBbox2D,
38
+ ): [minLon: number, minLat: number, maxLon: number, maxLat: number] {
39
+ return [
40
+ toMicroDegrees(bbox[0]),
41
+ toMicroDegrees(bbox[1]),
42
+ toMicroDegrees(bbox[2]),
43
+ toMicroDegrees(bbox[3]),
44
+ ]
45
+ }
@@ -1,5 +1,14 @@
1
1
  /**
2
- * Calculate the haversine distance between two LonLat points.
2
+ * Great-circle distance calculation using the Haversine formula.
3
+ *
4
+ * Computes the shortest distance between two points on a sphere,
5
+ * accounting for Earth's curvature. Accurate for most geographic distances.
6
+ *
7
+ * @module
8
+ */
9
+
10
+ /**
11
+ * Calculate the great-circle distance between two geographic points.
3
12
  * @param p1 - The first point
4
13
  * @param p2 - The second point
5
14
  * @returns The haversine distance in meters
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Progress event helpers for long-running operations.
3
+ *
4
+ * Provides a standard interface for reporting progress from workers and
5
+ * async operations. Uses CustomEvent for cross-context communication.
6
+ *
7
+ * @module
8
+ */
9
+
10
+ /**
11
+ * Progress payload containing a message and timestamp.
12
+ * Planned expansion to include percentage completion.
13
+ */
14
+ export type Progress = {
15
+ msg: string
16
+ timestamp: number
17
+ }
18
+
19
+ /** CustomEvent carrying progress details. */
20
+ export interface ProgressEvent extends CustomEvent<Progress> {}
21
+
22
+ /**
23
+ * Create a Progress payload with current timestamp.
24
+ * @param msg - The progress message.
25
+ */
26
+ export function progress(msg: string): Progress {
27
+ return {
28
+ msg,
29
+ timestamp: Date.now(),
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Create a ProgressEvent with the given message.
35
+ * @param msg - The progress message.
36
+ */
37
+ export function progressEvent(msg: string): ProgressEvent {
38
+ return new CustomEvent("progress", { detail: progress(msg) })
39
+ }
40
+
41
+ /**
42
+ * Extract the message string from a progress event.
43
+ * @param event - The event to extract from.
44
+ */
45
+ export function progressEventMessage(event: Event): string {
46
+ return (event as ProgressEvent).detail.msg
47
+ }
48
+
49
+ /**
50
+ * Log a progress event's message to the console.
51
+ * @param progress - The progress event to log.
52
+ */
53
+ export function logProgress(progress: ProgressEvent) {
54
+ console.log(progressEventMessage(progress))
55
+ }