@rybosome/tspice 0.0.3 → 0.0.8

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 (221) hide show
  1. package/README.md +145 -84
  2. package/backend-contract/dist/.tsbuildinfo +1 -1
  3. package/backend-contract/dist/domains/cells-windows.d.ts +94 -0
  4. package/backend-contract/dist/domains/cells-windows.js +10 -0
  5. package/backend-contract/dist/domains/coords-vectors.d.ts +53 -3
  6. package/backend-contract/dist/domains/dsk.d.ts +49 -0
  7. package/backend-contract/dist/domains/dsk.js +2 -0
  8. package/backend-contract/dist/domains/ek.d.ts +186 -0
  9. package/backend-contract/dist/domains/ek.js +8 -0
  10. package/backend-contract/dist/domains/ephemeris.d.ts +141 -3
  11. package/backend-contract/dist/domains/error.d.ts +42 -0
  12. package/backend-contract/dist/domains/error.js +33 -0
  13. package/backend-contract/dist/domains/file-io.d.ts +114 -0
  14. package/backend-contract/dist/domains/file-io.js +8 -0
  15. package/backend-contract/dist/domains/frames.d.ts +44 -4
  16. package/backend-contract/dist/domains/geometry-gf.d.ts +44 -0
  17. package/backend-contract/dist/domains/geometry-gf.js +14 -0
  18. package/backend-contract/dist/domains/geometry.d.ts +21 -1
  19. package/backend-contract/dist/domains/ids-names-normalize.d.ts +3 -0
  20. package/backend-contract/dist/domains/ids-names-normalize.js +74 -0
  21. package/backend-contract/dist/domains/ids-names.d.ts +37 -0
  22. package/backend-contract/dist/domains/kernel-pool.d.ts +134 -0
  23. package/backend-contract/dist/domains/kernel-pool.js +2 -0
  24. package/backend-contract/dist/domains/kernels-utils.d.ts +44 -0
  25. package/backend-contract/dist/domains/kernels-utils.js +265 -0
  26. package/backend-contract/dist/domains/kernels.d.ts +39 -3
  27. package/backend-contract/dist/domains/time.d.ts +102 -0
  28. package/backend-contract/dist/index.d.ts +34 -15
  29. package/backend-contract/dist/index.js +15 -1
  30. package/backend-contract/dist/shared/errors.d.ts +6 -0
  31. package/backend-contract/dist/shared/errors.js +8 -0
  32. package/backend-contract/dist/shared/mat3.d.ts +52 -0
  33. package/backend-contract/dist/shared/mat3.js +150 -0
  34. package/backend-contract/dist/shared/mat6.d.ts +34 -0
  35. package/backend-contract/dist/shared/mat6.js +116 -0
  36. package/backend-contract/dist/shared/spice-handles.d.ts +20 -0
  37. package/backend-contract/dist/shared/spice-handles.js +82 -0
  38. package/backend-contract/dist/shared/spice-int.d.ts +32 -0
  39. package/backend-contract/dist/shared/spice-int.js +41 -0
  40. package/backend-contract/dist/shared/types.d.ts +136 -5
  41. package/backend-contract/dist/shared/types.js +1 -1
  42. package/backend-contract/dist/shared/vec.d.ts +54 -0
  43. package/backend-contract/dist/shared/vec.js +162 -0
  44. package/backend-fake/dist/.tsbuildinfo +1 -1
  45. package/backend-fake/dist/index.d.ts +21 -1
  46. package/backend-fake/dist/index.js +1112 -33
  47. package/backend-node/dist/.tsbuildinfo +1 -1
  48. package/backend-node/dist/codec/arrays.d.ts +9 -0
  49. package/backend-node/dist/codec/arrays.js +36 -0
  50. package/backend-node/dist/codec/errors.d.ts +6 -6
  51. package/backend-node/dist/codec/errors.js +6 -6
  52. package/backend-node/dist/domains/cells-windows.d.ts +5 -0
  53. package/backend-node/dist/domains/cells-windows.js +112 -0
  54. package/backend-node/dist/domains/coords-vectors.d.ts +1 -0
  55. package/backend-node/dist/domains/coords-vectors.js +66 -0
  56. package/backend-node/dist/domains/dsk.d.ts +6 -0
  57. package/backend-node/dist/domains/dsk.js +108 -0
  58. package/backend-node/dist/domains/ek.d.ts +10 -0
  59. package/backend-node/dist/domains/ek.js +100 -0
  60. package/backend-node/dist/domains/ephemeris.d.ts +5 -1
  61. package/backend-node/dist/domains/ephemeris.js +150 -1
  62. package/backend-node/dist/domains/error.d.ts +5 -0
  63. package/backend-node/dist/domains/error.js +34 -0
  64. package/backend-node/dist/domains/file-io.d.ts +7 -0
  65. package/backend-node/dist/domains/file-io.js +105 -0
  66. package/backend-node/dist/domains/frames.d.ts +1 -0
  67. package/backend-node/dist/domains/frames.js +58 -6
  68. package/backend-node/dist/domains/geometry-gf.d.ts +5 -0
  69. package/backend-node/dist/domains/geometry-gf.js +74 -0
  70. package/backend-node/dist/domains/geometry.d.ts +1 -0
  71. package/backend-node/dist/domains/geometry.js +62 -0
  72. package/backend-node/dist/domains/ids-names.d.ts +2 -1
  73. package/backend-node/dist/domains/ids-names.js +30 -0
  74. package/backend-node/dist/domains/kernel-pool.d.ts +5 -0
  75. package/backend-node/dist/domains/kernel-pool.js +74 -0
  76. package/backend-node/dist/domains/kernels.d.ts +1 -0
  77. package/backend-node/dist/domains/kernels.js +100 -13
  78. package/backend-node/dist/domains/time.d.ts +1 -0
  79. package/backend-node/dist/domains/time.js +75 -1
  80. package/backend-node/dist/index.d.ts +5 -1
  81. package/backend-node/dist/index.js +62 -1
  82. package/backend-node/dist/lowlevel/binding.d.ts +3 -0
  83. package/backend-node/dist/lowlevel/binding.js +115 -0
  84. package/backend-node/dist/runtime/addon.d.ts +273 -2
  85. package/backend-node/dist/runtime/addon.js +3 -0
  86. package/backend-node/dist/runtime/kernel-staging.d.ts +17 -0
  87. package/backend-node/dist/runtime/kernel-staging.js +80 -7
  88. package/backend-node/dist/runtime/spice-handles.d.ts +3 -0
  89. package/backend-node/dist/runtime/spice-handles.js +2 -0
  90. package/backend-node/dist/runtime/virtual-output-staging.d.ts +16 -0
  91. package/backend-node/dist/runtime/virtual-output-staging.js +148 -0
  92. package/backend-wasm/dist/.tsbuildinfo +1 -1
  93. package/backend-wasm/dist/codec/alloc.d.ts +19 -0
  94. package/backend-wasm/dist/codec/alloc.js +64 -0
  95. package/backend-wasm/dist/codec/calls.d.ts +2 -0
  96. package/backend-wasm/dist/codec/calls.js +13 -24
  97. package/backend-wasm/dist/codec/errors.d.ts +6 -0
  98. package/backend-wasm/dist/codec/errors.js +34 -2
  99. package/backend-wasm/dist/codec/found.d.ts +2 -0
  100. package/backend-wasm/dist/codec/found.js +20 -43
  101. package/backend-wasm/dist/codec/strings.d.ts +31 -1
  102. package/backend-wasm/dist/codec/strings.js +93 -6
  103. package/backend-wasm/dist/domains/cells-windows.d.ts +9 -0
  104. package/backend-wasm/dist/domains/cells-windows.js +392 -0
  105. package/backend-wasm/dist/domains/coords-vectors.d.ts +1 -0
  106. package/backend-wasm/dist/domains/coords-vectors.js +377 -184
  107. package/backend-wasm/dist/domains/dsk.d.ts +6 -0
  108. package/backend-wasm/dist/domains/dsk.js +179 -0
  109. package/backend-wasm/dist/domains/ek.d.ts +6 -0
  110. package/backend-wasm/dist/domains/ek.js +543 -0
  111. package/backend-wasm/dist/domains/ephemeris.d.ts +4 -1
  112. package/backend-wasm/dist/domains/ephemeris.js +405 -46
  113. package/backend-wasm/dist/domains/error.d.ts +5 -0
  114. package/backend-wasm/dist/domains/error.js +109 -0
  115. package/backend-wasm/dist/domains/file-io.d.ts +7 -0
  116. package/backend-wasm/dist/domains/file-io.js +462 -0
  117. package/backend-wasm/dist/domains/frames.d.ts +1 -0
  118. package/backend-wasm/dist/domains/frames.js +139 -6
  119. package/backend-wasm/dist/domains/geometry-gf.d.ts +5 -0
  120. package/backend-wasm/dist/domains/geometry-gf.js +178 -0
  121. package/backend-wasm/dist/domains/geometry.d.ts +1 -0
  122. package/backend-wasm/dist/domains/geometry.js +210 -0
  123. package/backend-wasm/dist/domains/ids-names.d.ts +2 -1
  124. package/backend-wasm/dist/domains/ids-names.js +89 -0
  125. package/backend-wasm/dist/domains/kernel-pool.d.ts +5 -0
  126. package/backend-wasm/dist/domains/kernel-pool.js +357 -0
  127. package/backend-wasm/dist/domains/kernels.d.ts +1 -0
  128. package/backend-wasm/dist/domains/kernels.js +108 -4
  129. package/backend-wasm/dist/domains/time.d.ts +2 -0
  130. package/backend-wasm/dist/domains/time.js +235 -133
  131. package/backend-wasm/dist/index.d.ts +4 -2
  132. package/backend-wasm/dist/lowlevel/exports.d.ts +215 -1
  133. package/backend-wasm/dist/lowlevel/exports.js +217 -38
  134. package/backend-wasm/dist/runtime/create-backend-options.d.ts +21 -0
  135. package/backend-wasm/dist/runtime/create-backend.node.d.ts +11 -2
  136. package/backend-wasm/dist/runtime/create-backend.node.js +283 -14
  137. package/backend-wasm/dist/runtime/create-backend.web.d.ts +5 -2
  138. package/backend-wasm/dist/runtime/create-backend.web.js +40 -6
  139. package/backend-wasm/dist/runtime/fs.d.ts +6 -0
  140. package/backend-wasm/dist/runtime/fs.js +29 -3
  141. package/backend-wasm/dist/runtime/spice-handles.d.ts +3 -0
  142. package/backend-wasm/dist/runtime/spice-handles.js +2 -0
  143. package/backend-wasm/dist/runtime/virtual-outputs.d.ts +16 -0
  144. package/backend-wasm/dist/runtime/virtual-outputs.js +35 -0
  145. package/backend-wasm/dist/tspice_backend_wasm.node.js +3 -3
  146. package/backend-wasm/dist/tspice_backend_wasm.wasm +0 -0
  147. package/backend-wasm/dist/tspice_backend_wasm.web.js +1 -1
  148. package/core/dist/.tsbuildinfo +1 -1
  149. package/core/dist/index.d.ts +21 -0
  150. package/core/dist/index.js +57 -0
  151. package/dist/.tsbuildinfo +1 -1
  152. package/dist/backend.d.ts +15 -6
  153. package/dist/backend.js +3 -6
  154. package/dist/clients/createSpiceAsyncFromTransport.d.ts +5 -0
  155. package/dist/clients/createSpiceAsyncFromTransport.js +90 -0
  156. package/dist/clients/createSpiceSyncFromTransport.d.ts +5 -0
  157. package/dist/clients/createSpiceSyncFromTransport.js +88 -0
  158. package/dist/clients/spiceClients.d.ts +59 -0
  159. package/dist/clients/spiceClients.js +292 -0
  160. package/dist/errors.d.ts +4 -0
  161. package/dist/errors.js +4 -0
  162. package/dist/index.d.ts +12 -7
  163. package/dist/index.js +5 -2
  164. package/dist/kernels/defaultKernelPathFromUrl.d.ts +8 -0
  165. package/dist/kernels/defaultKernelPathFromUrl.js +32 -0
  166. package/dist/kernels/kernelPack.d.ts +88 -0
  167. package/dist/kernels/kernelPack.js +122 -0
  168. package/dist/kernels/kernels.d.ts +98 -0
  169. package/dist/kernels/kernels.js +217 -0
  170. package/dist/kernels/naifKernelId.d.ts +2 -0
  171. package/dist/kernels/naifKernelId.js +2 -0
  172. package/dist/kit/index.d.ts +4 -0
  173. package/dist/kit/index.js +3 -0
  174. package/dist/kit/math/mat3.d.ts +31 -0
  175. package/dist/kit/math/mat3.js +82 -0
  176. package/dist/kit/spice/create-kit.d.ts +12 -0
  177. package/dist/kit/spice/create-kit.js +23 -0
  178. package/dist/kit/spice/frames.d.ts +8 -0
  179. package/dist/kit/spice/frames.js +16 -0
  180. package/dist/kit/spice/kernels.d.ts +14 -0
  181. package/dist/kit/spice/kernels.js +39 -0
  182. package/dist/kit/spice/state.d.ts +7 -0
  183. package/dist/kit/spice/state.js +36 -0
  184. package/dist/kit/spice/time.d.ts +9 -0
  185. package/dist/kit/spice/time.js +31 -0
  186. package/dist/kit/types/spice-types.d.ts +51 -0
  187. package/dist/spice.d.ts +10 -1
  188. package/dist/spice.js +84 -72
  189. package/dist/transport/caching/policy.d.ts +16 -0
  190. package/dist/transport/caching/policy.js +77 -0
  191. package/dist/transport/caching/withCaching.d.ts +125 -0
  192. package/dist/transport/caching/withCaching.js +335 -0
  193. package/dist/transport/caching/withCachingSync.d.ts +24 -0
  194. package/dist/transport/caching/withCachingSync.js +161 -0
  195. package/dist/transport/rpc/protocol.d.ts +35 -0
  196. package/dist/transport/rpc/protocol.js +56 -0
  197. package/dist/transport/rpc/taskScheduling.d.ts +20 -0
  198. package/dist/transport/rpc/taskScheduling.js +98 -0
  199. package/dist/transport/rpc/valueCodec.d.ts +5 -0
  200. package/dist/transport/rpc/valueCodec.js +106 -0
  201. package/dist/transport/types.d.ts +7 -0
  202. package/dist/transport/types.js +2 -0
  203. package/dist/types.d.ts +8 -17
  204. package/dist/types.js +2 -1
  205. package/dist/worker/browser/createSpiceWorker.d.ts +22 -0
  206. package/dist/worker/browser/createSpiceWorker.js +41 -0
  207. package/dist/worker/browser/createSpiceWorkerClient.d.ts +40 -0
  208. package/dist/worker/browser/createSpiceWorkerClient.js +99 -0
  209. package/dist/worker/browser/spiceWorkerEntry.d.ts +2 -0
  210. package/dist/worker/browser/spiceWorkerEntry.js +129 -0
  211. package/dist/worker/browser/spiceWorkerInlineSource.d.ts +2 -0
  212. package/dist/worker/browser/spiceWorkerInlineSource.js +4 -0
  213. package/dist/worker/index.d.ts +10 -0
  214. package/dist/worker/index.js +7 -0
  215. package/dist/worker/transport/createWorkerTransport.d.ts +69 -0
  216. package/dist/worker/transport/createWorkerTransport.js +398 -0
  217. package/dist/worker/transport/exposeTransportToWorker.d.ts +51 -0
  218. package/dist/worker/transport/exposeTransportToWorker.js +196 -0
  219. package/package.json +4 -4
  220. package/dist/spice-types.d.ts +0 -36
  221. /package/dist/{spice-types.js → kit/types/spice-types.js} +0 -0
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Probe whether a true macrotask scheduler is available in the current runtime
3
+ * (without actually scheduling a task).
4
+ */
5
+ export function canQueueMacrotask() {
6
+ // Prefer MessageChannel when available.
7
+ //
8
+ // Important: if MessageChannel exists but is broken (e.g. constructible but
9
+ // `postMessage` throws), we fall through to `setTimeout` rather than failing
10
+ // closed. This matches `queueMacrotask()` behavior.
11
+ if (typeof MessageChannel !== "undefined") {
12
+ try {
13
+ const { port1, port2 } = new MessageChannel();
14
+ try {
15
+ // Probe that `postMessage` works (some polyfills allow construction but
16
+ // throw on `postMessage`, which would otherwise deadlock queueing).
17
+ port2.postMessage(undefined);
18
+ return true;
19
+ }
20
+ finally {
21
+ // Always close ports so they don't keep the event loop alive in Node.
22
+ // Be defensive: some polyfills/test environments may not implement `close()`.
23
+ try {
24
+ port1.close?.();
25
+ }
26
+ catch {
27
+ // ignore
28
+ }
29
+ try {
30
+ port2.close?.();
31
+ }
32
+ catch {
33
+ // ignore
34
+ }
35
+ }
36
+ }
37
+ catch {
38
+ // Ignore and fall back to setTimeout.
39
+ }
40
+ }
41
+ return typeof setTimeout === "function";
42
+ }
43
+ /** Queue `fn` on the next macrotask (MessageChannel preferred; setTimeout fallback). */
44
+ export function queueMacrotask(fn, opts) {
45
+ const allowSyncFallback = opts?.allowSyncFallback ?? true;
46
+ // Prefer MessageChannel when available. This schedules a real task boundary
47
+ // without relying on timers, which makes it friendlier to fake-timer test
48
+ // environments.
49
+ try {
50
+ if (typeof MessageChannel !== "undefined") {
51
+ const { port1, port2 } = new MessageChannel();
52
+ const port1WithOnMessage = port1;
53
+ port1WithOnMessage.onmessage = () => {
54
+ port1WithOnMessage.onmessage = null;
55
+ // Close ports so this doesn't keep the event loop alive in Node.
56
+ // Be defensive: some polyfills/test environments may not implement
57
+ // `close()`.
58
+ try {
59
+ port1.close?.();
60
+ }
61
+ catch {
62
+ // ignore
63
+ }
64
+ try {
65
+ port2.close?.();
66
+ }
67
+ catch {
68
+ // ignore
69
+ }
70
+ fn();
71
+ };
72
+ port2.postMessage(undefined);
73
+ return true;
74
+ }
75
+ }
76
+ catch {
77
+ // Ignore and fall back to setTimeout.
78
+ }
79
+ // Next preference: a real macrotask via setTimeout.
80
+ if (typeof setTimeout === "function") {
81
+ setTimeout(fn, 0);
82
+ return true;
83
+ }
84
+ // No macrotask scheduler available in this runtime.
85
+ if (allowSyncFallback)
86
+ fn();
87
+ return false;
88
+ }
89
+ /** Return a promise that resolves on the next macrotask boundary (rejects if unavailable). */
90
+ export function nextMacrotask() {
91
+ return new Promise((resolve, reject) => {
92
+ const ok = queueMacrotask(resolve, { allowSyncFallback: false });
93
+ if (!ok) {
94
+ reject(new Error("nextMacrotask(): no macrotask scheduler available (MessageChannel/setTimeout missing)"));
95
+ }
96
+ });
97
+ }
98
+ //# sourceMappingURL=taskScheduling.js.map
@@ -0,0 +1,5 @@
1
+ /** Encode an arbitrary value into a structured-clone-safe shape. */
2
+ export declare function encodeRpcValue(value: unknown): unknown;
3
+ /** Decode a value that was encoded by {@link encodeRpcValue}. */
4
+ export declare function decodeRpcValue(value: unknown): unknown;
5
+ //# sourceMappingURL=valueCodec.d.ts.map
@@ -0,0 +1,106 @@
1
+ import { Mat3 } from "../../kit/math/mat3.js";
2
+ /**
3
+ * Values sent across the worker boundary must be structured-clone-safe.
4
+ *
5
+ * This codec provides a minimal, extensible tagged encoding for non-plain
6
+ * objects (e.g. `Mat3`) used by the tspice API.
7
+ */
8
+ const tspiceRpcTagKey = "__tspiceRpcTag";
9
+ function isRecord(value) {
10
+ return value !== null && typeof value === "object";
11
+ }
12
+ function isTaggedRecord(value) {
13
+ return isRecord(value) && tspiceRpcTagKey in value;
14
+ }
15
+ function isFiniteNumber(value) {
16
+ return typeof value === "number" && Number.isFinite(value);
17
+ }
18
+ function isMat3RowMajorData(value) {
19
+ return (Array.isArray(value) && value.length === 9 && value.every(isFiniteNumber));
20
+ }
21
+ /** Encode an arbitrary value into a structured-clone-safe shape. */
22
+ export function encodeRpcValue(value) {
23
+ if (value instanceof Mat3) {
24
+ const data = Array.from(value.rowMajor);
25
+ return {
26
+ [tspiceRpcTagKey]: "Mat3",
27
+ layout: "rowMajor",
28
+ data,
29
+ };
30
+ }
31
+ if (Array.isArray(value)) {
32
+ return value.map(encodeRpcValue);
33
+ }
34
+ // Fast-path: ArrayBuffer + views (TypedArrays/DataView) are structured-clone-
35
+ // safe and should pass through unchanged. This is important for transferring
36
+ // kernel bytes (e.g. Uint8Array) into a worker.
37
+ if (value instanceof ArrayBuffer)
38
+ return value;
39
+ if (ArrayBuffer.isView(value))
40
+ return value;
41
+ // SharedArrayBuffer exists in some environments (Node, some browsers) but is
42
+ // gated by cross-origin isolation in browsers. Allow it when present.
43
+ if (typeof SharedArrayBuffer !== "undefined" &&
44
+ value instanceof SharedArrayBuffer) {
45
+ return value;
46
+ }
47
+ if (isRecord(value)) {
48
+ // Allow byte buffers/typed arrays to cross the worker boundary.
49
+ // These are structured-clone-safe and commonly used for kernel outputs.
50
+ if (value instanceof ArrayBuffer)
51
+ return value;
52
+ if (ArrayBuffer.isView(value))
53
+ return value;
54
+ if (typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer) {
55
+ return value;
56
+ }
57
+ // Preserve Date/Map/Set/etc as-is? No: those are not guaranteed to be
58
+ // structured-clone-safe across all targets. For now, we only support plain
59
+ // object literals.
60
+ const proto = Object.getPrototypeOf(value);
61
+ if (proto !== Object.prototype && proto !== null) {
62
+ const ctorName = value.constructor?.name ??
63
+ proto.constructor?.name;
64
+ throw new Error("encodeRpcValue(): unsupported non-plain object for worker RPC " +
65
+ `(constructor=${String(ctorName)}). ` +
66
+ "Pass plain objects/arrays/primitives or extend the codec.");
67
+ }
68
+ const out = {};
69
+ for (const [k, v] of Object.entries(value)) {
70
+ out[k] = encodeRpcValue(v);
71
+ }
72
+ return out;
73
+ }
74
+ return value;
75
+ }
76
+ /** Decode a value that was encoded by {@link encodeRpcValue}. */
77
+ export function decodeRpcValue(value) {
78
+ if (isTaggedRecord(value)) {
79
+ const tag = value[tspiceRpcTagKey];
80
+ if (tag === "Mat3") {
81
+ const layout = value.layout;
82
+ const data = value.data;
83
+ if (layout === "rowMajor" && isMat3RowMajorData(data)) {
84
+ // Mat3.fromRowMajor expects a branded Mat3RowMajor type. We validated
85
+ // the runtime shape here, so the cast is safe.
86
+ return Mat3.fromRowMajor(data);
87
+ }
88
+ }
89
+ }
90
+ if (Array.isArray(value)) {
91
+ return value.map(decodeRpcValue);
92
+ }
93
+ if (isRecord(value)) {
94
+ // Preserve non-plain objects (e.g. TypedArrays) as-is.
95
+ const proto = Object.getPrototypeOf(value);
96
+ if (proto !== Object.prototype && proto !== null)
97
+ return value;
98
+ const out = {};
99
+ for (const [k, v] of Object.entries(value)) {
100
+ out[k] = decodeRpcValue(v);
101
+ }
102
+ return out;
103
+ }
104
+ return value;
105
+ }
106
+ //# sourceMappingURL=valueCodec.js.map
@@ -0,0 +1,7 @@
1
+ export type SpiceTransport = {
2
+ request(op: string, args: unknown[]): Promise<unknown>;
3
+ };
4
+ export type SpiceTransportSync = {
5
+ request(op: string, args: unknown[]): unknown;
6
+ };
7
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
package/dist/types.d.ts CHANGED
@@ -9,25 +9,16 @@ export type Vec6 = readonly [
9
9
  number,
10
10
  number
11
11
  ];
12
- /** 3x3 matrix, row-major. */
13
- export type Mat3 = readonly [
14
- number,
15
- number,
16
- number,
17
- number,
18
- number,
19
- number,
20
- number,
21
- number,
22
- number
23
- ];
24
12
  /** SPICE frame name (e.g. "J2000", "IAU_EARTH"). */
25
13
  export type FrameName = string;
14
+ /** Canonical inertial reference frame. */
15
+ export declare const J2000: "J2000";
26
16
  /** Aberration correction string accepted by `spkezr`. */
27
17
  export type AberrationCorrection = "NONE" | "LT" | "LT+S" | "CN" | "CN+S" | "XLT" | "XLT+S" | "XCN" | "XCN+S";
28
- export type SpiceTime = number & {
29
- readonly __tspiceBrand: "SpiceTime";
30
- };
18
+ /** Seconds past J2000 (ET). */
19
+ export type SpiceTime = number;
20
+ /** Body identifier accepted by kit APIs (name or NAIF id). */
21
+ export type BodyRef = string | number;
31
22
  export type StateVector = {
32
23
  /** Seconds past J2000 (ET). */
33
24
  et: SpiceTime;
@@ -45,8 +36,8 @@ export type StateVector = {
45
36
  lightTime: number;
46
37
  };
47
38
  export type GetStateArgs = {
48
- target: string;
49
- observer: string;
39
+ target: BodyRef;
40
+ observer: BodyRef;
50
41
  at: SpiceTime;
51
42
  frame?: FrameName;
52
43
  aberration?: AberrationCorrection;
package/dist/types.js CHANGED
@@ -1,2 +1,3 @@
1
- export {};
1
+ /** Canonical inertial reference frame. */
2
+ export const J2000 = "J2000";
2
3
  //# sourceMappingURL=types.js.map
@@ -0,0 +1,22 @@
1
+ import type { WorkerLike } from "../transport/createWorkerTransport.js";
2
+ export type CreateSpiceWorkerOptions = {
3
+ /** Override the worker entrypoint (advanced). */
4
+ url?: string | URL;
5
+ /**
6
+ * Override the WASM binary URL used by the default inline worker.
7
+ *
8
+ * When omitted, `createSpiceWorker()` will resolve the WASM binary URL
9
+ * relative to the published package layout.
10
+ */
11
+ wasmUrl?: string | URL;
12
+ /**
13
+ * Options passed through to the `Worker` constructor.
14
+ *
15
+ * Typed loosely on purpose so this package doesn't require `lib.dom` types
16
+ * (and so it can be consumed in non-DOM TS configs).
17
+ */
18
+ workerOptions?: Record<string, unknown>;
19
+ };
20
+ /** Create a Web Worker instance for the tspice worker entrypoint (inline by default). */
21
+ export declare function createSpiceWorker(opts?: CreateSpiceWorkerOptions): WorkerLike;
22
+ //# sourceMappingURL=createSpiceWorker.d.ts.map
@@ -0,0 +1,41 @@
1
+ import { SPICE_WORKER_INLINE_SOURCE } from "./spiceWorkerInlineSource.js";
2
+ /** Create a Web Worker instance for the tspice worker entrypoint (inline by default). */
3
+ export function createSpiceWorker(opts = {}) {
4
+ const WorkerCtor = globalThis.Worker;
5
+ if (typeof WorkerCtor !== "function") {
6
+ throw new Error("createSpiceWorker() requires Web Worker support in the current runtime");
7
+ }
8
+ // Default to module workers since this package is ESM and relies on
9
+ // ESM-only dependencies.
10
+ const workerOptions = {
11
+ type: "module",
12
+ ...(opts.workerOptions ?? {}),
13
+ };
14
+ if (opts.url != null) {
15
+ return new WorkerCtor(opts.url, workerOptions);
16
+ }
17
+ // Inline (blob) worker by default.
18
+ //
19
+ // This avoids requiring consumers to separately bundle/host a worker JS asset
20
+ // URL. It also means the worker entry cannot use `import.meta.url` to locate
21
+ // assets, since the entrypoint URL will be `blob:`.
22
+ if (workerOptions.type !== "module") {
23
+ throw new Error('createSpiceWorker() inline worker requires a module worker (workerOptions.type="module")');
24
+ }
25
+ const wasmUrl = opts.wasmUrl?.toString() ??
26
+ // Published package layout (and what `build:dist-publish` produces):
27
+ // dist/worker/browser/createSpiceWorker.js
28
+ // backend-wasm/dist/tspice_backend_wasm.wasm
29
+ new URL("../../../backend-wasm/dist/tspice_backend_wasm.wasm", import.meta.url).href;
30
+ const workerSource = `globalThis.__TSPICE_WORKER_CONFIG__ = ${JSON.stringify({ wasmUrl })};\n` +
31
+ SPICE_WORKER_INLINE_SOURCE;
32
+ const blob = new Blob([workerSource], { type: "text/javascript" });
33
+ const blobUrl = URL.createObjectURL(blob);
34
+ try {
35
+ return new WorkerCtor(blobUrl, workerOptions);
36
+ }
37
+ finally {
38
+ URL.revokeObjectURL(blobUrl);
39
+ }
40
+ }
41
+ //# sourceMappingURL=createSpiceWorker.js.map
@@ -0,0 +1,40 @@
1
+ import type { SpiceAsync } from "../../kit/types/spice-types.js";
2
+ import type { SpiceTransport } from "../../transport/types.js";
3
+ import { type WorkerLike, type WorkerTransport } from "../transport/createWorkerTransport.js";
4
+ export type SpiceWorkerClient<TTransport extends SpiceTransport = WorkerTransport> = {
5
+ worker: WorkerLike;
6
+ /** The underlying request/response RPC transport (always a WorkerTransport). */
7
+ baseTransport: WorkerTransport;
8
+ /** The transport after applying `wrapTransport` (e.g. `withCaching`). */
9
+ transport: TTransport;
10
+ /** A `SpiceAsync` client backed by `transport`. */
11
+ spice: SpiceAsync;
12
+ /** Dispose wrapper transport (if any) and the worker transport. */
13
+ dispose: () => void;
14
+ /**
15
+ * Async dispose variant that awaits wrapper transport cleanup (if any) before
16
+ * disposing the underlying worker transport.
17
+ */
18
+ disposeAsync: () => Promise<void>;
19
+ };
20
+ export type CreateSpiceWorkerClientOptions<TTransport extends SpiceTransport = WorkerTransport> = {
21
+ /**
22
+ * Pass an existing Worker or a factory to create one.
23
+ *
24
+ * Defaults to `() => createSpiceWorker()`.
25
+ */
26
+ worker?: WorkerLike | (() => WorkerLike);
27
+ /** Default request timeout forwarded to `createWorkerTransport`. */
28
+ timeoutMs?: number;
29
+ /** Forwarded to `createWorkerTransport`. Defaults to `true` when `worker` is a factory. */
30
+ terminateOnDispose?: boolean;
31
+ /** Forwarded to `createWorkerTransport`. Defaults to `terminateOnDispose`. */
32
+ signalDispose?: boolean;
33
+ /** Optional transport wrapper (e.g. `withCaching`). */
34
+ wrapTransport?: (t: WorkerTransport) => TTransport;
35
+ /** Called if `disposeAsync()` rejects when invoked via fire-and-forget `dispose()`. */
36
+ onDisposeError?: (err: unknown) => void;
37
+ };
38
+ /** Create a {@link SpiceWorkerClient} that communicates with a tspice Web Worker via RPC. */
39
+ export declare function createSpiceWorkerClient<TTransport extends SpiceTransport = WorkerTransport>(opts?: CreateSpiceWorkerClientOptions<TTransport>): SpiceWorkerClient<TTransport>;
40
+ //# sourceMappingURL=createSpiceWorkerClient.d.ts.map
@@ -0,0 +1,99 @@
1
+ import { createSpiceAsyncFromTransport } from "../../clients/createSpiceAsyncFromTransport.js";
2
+ import { createWorkerTransport, } from "../transport/createWorkerTransport.js";
3
+ import { createSpiceWorker } from "./createSpiceWorker.js";
4
+ function getDisposeFn(value) {
5
+ if (value === null)
6
+ return undefined;
7
+ const t = typeof value;
8
+ if (t !== "object" && t !== "function")
9
+ return undefined;
10
+ const dispose = value.dispose;
11
+ return typeof dispose === "function" ? dispose : undefined;
12
+ }
13
+ function isPromiseLike(value) {
14
+ if (value === null)
15
+ return false;
16
+ const t = typeof value;
17
+ if (t !== "object" && t !== "function")
18
+ return false;
19
+ return typeof value.then === "function";
20
+ }
21
+ /** Create a {@link SpiceWorkerClient} that communicates with a tspice Web Worker via RPC. */
22
+ export function createSpiceWorkerClient(opts) {
23
+ const workerInput = opts?.worker ?? (() => createSpiceWorker());
24
+ const worker = typeof workerInput === "function" ? workerInput() : workerInput;
25
+ const terminateOnDispose = opts?.terminateOnDispose ??
26
+ (typeof workerInput === "function" ? true : false);
27
+ const baseTransport = createWorkerTransport({
28
+ worker,
29
+ ...(opts?.timeoutMs === undefined ? {} : { timeoutMs: opts.timeoutMs }),
30
+ terminateOnDispose,
31
+ ...(opts?.signalDispose === undefined
32
+ ? {}
33
+ : { signalDispose: opts.signalDispose }),
34
+ });
35
+ const transport = opts?.wrapTransport
36
+ ? opts.wrapTransport(baseTransport)
37
+ : baseTransport;
38
+ const spice = createSpiceAsyncFromTransport(transport);
39
+ let disposePromise;
40
+ const disposeAsync = () => {
41
+ if (disposePromise)
42
+ return disposePromise;
43
+ disposePromise = (async () => {
44
+ try {
45
+ // If a wrapper transport supports cleanup, run it before disposing the
46
+ // underlying worker transport.
47
+ if (transport !== baseTransport) {
48
+ const wrapperDispose = getDisposeFn(transport);
49
+ if (wrapperDispose) {
50
+ const result = wrapperDispose.call(transport);
51
+ if (isPromiseLike(result))
52
+ await result;
53
+ }
54
+ }
55
+ }
56
+ finally {
57
+ baseTransport.dispose();
58
+ }
59
+ })();
60
+ return disposePromise;
61
+ };
62
+ const dispose = () => {
63
+ // Fire-and-forget. Ensure we don't surface unhandled rejections if wrapper
64
+ // cleanup fails.
65
+ void disposeAsync().catch((err) => {
66
+ try {
67
+ opts?.onDisposeError?.(err);
68
+ }
69
+ catch (callbackErr) {
70
+ if (typeof console !== "undefined" &&
71
+ typeof console.error === "function") {
72
+ // Log both: the original disposal failure and the error thrown by the
73
+ // error callback.
74
+ try {
75
+ console.error("createSpiceWorkerClient.dispose(): disposeAsync() failed", err);
76
+ }
77
+ catch {
78
+ // ignore
79
+ }
80
+ try {
81
+ console.error("createSpiceWorkerClient.dispose(): onDisposeError threw", callbackErr);
82
+ }
83
+ catch {
84
+ // ignore
85
+ }
86
+ }
87
+ }
88
+ });
89
+ };
90
+ return {
91
+ worker,
92
+ baseTransport,
93
+ transport,
94
+ spice,
95
+ dispose,
96
+ disposeAsync,
97
+ };
98
+ }
99
+ //# sourceMappingURL=createSpiceWorkerClient.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spiceWorkerEntry.d.ts.map
@@ -0,0 +1,129 @@
1
+ import { createSpiceAsync } from "../../spice.js";
2
+ import { exposeTransportToWorker } from "../transport/exposeTransportToWorker.js";
3
+ const getWorkerConfig = () => {
4
+ const cfg = globalThis
5
+ .__TSPICE_WORKER_CONFIG__;
6
+ if (!cfg || typeof cfg !== "object")
7
+ return undefined;
8
+ return cfg;
9
+ };
10
+ const blockedStringKeys = new Set([
11
+ // Promise / thenable
12
+ "then",
13
+ // Prototype / constructor escapes
14
+ "__proto__",
15
+ "prototype",
16
+ "constructor",
17
+ // Common stringification / inspection hooks
18
+ "toJSON",
19
+ "inspect",
20
+ // Object.prototype keys (avoid accidental RPC calls during introspection)
21
+ "toString",
22
+ "valueOf",
23
+ "toLocaleString",
24
+ "hasOwnProperty",
25
+ "isPrototypeOf",
26
+ "propertyIsEnumerable",
27
+ "__defineGetter__",
28
+ "__defineSetter__",
29
+ "__lookupGetter__",
30
+ "__lookupSetter__",
31
+ ]);
32
+ const isSafeRpcKey = (key) => /^[A-Za-z_$][\w$]*$/.test(key);
33
+ const allowedKitMethodList = [
34
+ "loadKernel",
35
+ "unloadKernel",
36
+ "kclear",
37
+ "toolkitVersion",
38
+ "utcToEt",
39
+ "etToUtc",
40
+ "frameTransform",
41
+ "getState",
42
+ ];
43
+ const defaultAllowlist = {
44
+ // NOTE: `kit` is deliberately allowlisted because it's a small, curated API.
45
+ // `raw` is intentionally not allowlisted here (see module comment below).
46
+ kit: new Set(allowedKitMethodList),
47
+ };
48
+ function createSpiceTransportFromSpiceAsync(spice, opts) {
49
+ const allowlist = opts?.allowlist ?? defaultAllowlist;
50
+ return {
51
+ request: async (op, args) => {
52
+ const dot = op.indexOf(".");
53
+ if (dot <= 0 || dot === op.length - 1) {
54
+ throw new Error(`Invalid op: ${op}`);
55
+ }
56
+ const namespace = op.slice(0, dot);
57
+ const method = op.slice(dot + 1);
58
+ if (namespace !== "raw" && namespace !== "kit") {
59
+ throw new Error(`Unknown namespace: ${namespace}`);
60
+ }
61
+ if (!isSafeRpcKey(method) || blockedStringKeys.has(method)) {
62
+ throw new Error(`Invalid method name: ${method}`);
63
+ }
64
+ const ns = namespace;
65
+ const nsAllowlist = allowlist[ns];
66
+ if (nsAllowlist && !nsAllowlist.has(method)) {
67
+ throw new Error(`Disallowed op: ${op}`);
68
+ }
69
+ const target = spice[ns];
70
+ const fn = target[method];
71
+ if (typeof fn !== "function") {
72
+ throw new Error(`Unknown op: ${op}`);
73
+ }
74
+ // `spice.raw` and `spice.kit` are proxies that return bound/wrapped
75
+ // functions, but use Reflect.apply to be defensive about `this`.
76
+ return await Reflect.apply(fn, target, args);
77
+ },
78
+ };
79
+ }
80
+ // NOTE: This file is meant to be loaded as a Web Worker module.
81
+ // It intentionally has no exports and runs as a side-effect.
82
+ //
83
+ // Security/design note:
84
+ // - This worker entry is intended for internal workspace use.
85
+ // - By default, it exposes:
86
+ // - `kit.*` as a small, curated allowlist (see `allowedKitMethodList`), and
87
+ // - `raw.*` without an allowlist (subject to the blocked key checks above).
88
+ // - If you need a tighter RPC capability set (especially for `raw.*`), create
89
+ // a custom worker entry and provide an explicit allowlist.
90
+ //
91
+ // IMPORTANT: `exposeTransportToWorker()` must run synchronously so the worker's
92
+ // `message` handler is installed immediately. Otherwise, early RPC messages from
93
+ // the main thread can be dropped while the WASM backend is still initializing.
94
+ let spicePromise;
95
+ let transportPromise;
96
+ const getSpicePromise = () => {
97
+ if (spicePromise)
98
+ return spicePromise;
99
+ const config = getWorkerConfig();
100
+ const wasmUrl = config?.wasmUrl;
101
+ spicePromise = createSpiceAsync({
102
+ backend: "wasm",
103
+ ...(wasmUrl === undefined ? {} : { wasmUrl }),
104
+ });
105
+ return spicePromise;
106
+ };
107
+ const getTransportPromise = () => (transportPromise ??= getSpicePromise().then((spice) => createSpiceTransportFromSpiceAsync(spice)));
108
+ exposeTransportToWorker({
109
+ transport: {
110
+ request: async (op, args) => (await getTransportPromise()).request(op, args),
111
+ },
112
+ onDispose: async () => {
113
+ // Best-effort cleanup. Worker termination also releases resources, but this
114
+ // helps callers who keep the worker alive.
115
+ if (!spicePromise) {
116
+ return;
117
+ }
118
+ try {
119
+ const spice = await getSpicePromise();
120
+ await spice.raw.kclear();
121
+ }
122
+ catch {
123
+ // ignore
124
+ }
125
+ },
126
+ });
127
+ // Kick off init after the `message` handler has been installed.
128
+ void getTransportPromise();
129
+ //# sourceMappingURL=spiceWorkerEntry.js.map
@@ -0,0 +1,2 @@
1
+ export declare const SPICE_WORKER_INLINE_SOURCE: string;
2
+ //# sourceMappingURL=spiceWorkerInlineSource.d.ts.map