@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,108 @@
1
+ import { invariant } from "#core";
2
+ const I32_MIN = -2147483648;
3
+ const I32_MAX = 2147483647;
4
+ const DAS_BACKED = ["DAS", "DLA"];
5
+ function assertDlaDescriptor(value, context) {
6
+ invariant(typeof value === "object" && value !== null, `${context}: expected an object`);
7
+ const obj = value;
8
+ for (const key of [
9
+ "bwdptr",
10
+ "fwdptr",
11
+ "ibase",
12
+ "isize",
13
+ "dbase",
14
+ "dsize",
15
+ "cbase",
16
+ "csize",
17
+ ]) {
18
+ const v = obj[key];
19
+ invariant(typeof v === "number" &&
20
+ Number.isInteger(v) &&
21
+ v >= I32_MIN &&
22
+ v <= I32_MAX, `${context}: expected ${key} to be a 32-bit signed integer`);
23
+ }
24
+ }
25
+ function assertI32(value, context) {
26
+ invariant(typeof value === "number" &&
27
+ Number.isInteger(value) &&
28
+ value >= I32_MIN &&
29
+ value <= I32_MAX, `${context}: expected a 32-bit signed integer`);
30
+ }
31
+ function assertFiniteNumber(value, context) {
32
+ invariant(typeof value === "number" && Number.isFinite(value), `${context}: expected a finite number`);
33
+ }
34
+ function normalizeDskDescriptor(value, context) {
35
+ invariant(typeof value === "object" && value !== null, `${context}: expected an object`);
36
+ const obj = value;
37
+ for (const k of ["surfce", "center", "dclass", "dtype", "frmcde", "corsys"]) {
38
+ assertI32(obj[k], `${context}.${k}`);
39
+ }
40
+ invariant(Array.isArray(obj.corpar), `${context}.corpar: expected an array`);
41
+ invariant(obj.corpar.length === 10, `${context}.corpar: expected length 10`);
42
+ for (let i = 0; i < obj.corpar.length; i++) {
43
+ assertFiniteNumber(obj.corpar[i], `${context}.corpar[${i}]`);
44
+ }
45
+ for (const k of [
46
+ "co1min",
47
+ "co1max",
48
+ "co2min",
49
+ "co2max",
50
+ "co3min",
51
+ "co3max",
52
+ "start",
53
+ "stop",
54
+ ]) {
55
+ assertFiniteNumber(obj[k], `${context}.${k}`);
56
+ }
57
+ return obj;
58
+ }
59
+ function normalizeDskType2Bookkeeping(value, context) {
60
+ invariant(typeof value === "object" && value !== null, `${context}: expected an object`);
61
+ const obj = value;
62
+ for (const k of ["nv", "np", "nvxtot", "cgscal", "vtxnpl", "voxnpt", "voxnpl"]) {
63
+ assertI32(obj[k], `${context}.${k}`);
64
+ }
65
+ invariant(Array.isArray(obj.vtxbds), `${context}.vtxbds: expected an array`);
66
+ invariant(obj.vtxbds.length === 3, `${context}.vtxbds: expected length 3`);
67
+ for (let axis = 0; axis < 3; axis++) {
68
+ const pair = obj.vtxbds[axis];
69
+ invariant(Array.isArray(pair), `${context}.vtxbds[${axis}]: expected an array`);
70
+ invariant(pair.length === 2, `${context}.vtxbds[${axis}]: expected length 2`);
71
+ assertFiniteNumber(pair[0], `${context}.vtxbds[${axis}][0]`);
72
+ assertFiniteNumber(pair[1], `${context}.vtxbds[${axis}][1]`);
73
+ }
74
+ assertFiniteNumber(obj.voxsiz, `${context}.voxsiz`);
75
+ invariant(Array.isArray(obj.voxori), `${context}.voxori: expected an array`);
76
+ invariant(obj.voxori.length === 3, `${context}.voxori: expected length 3`);
77
+ for (let i = 0; i < 3; i++) {
78
+ assertFiniteNumber(obj.voxori[i], `${context}.voxori[${i}]`);
79
+ }
80
+ invariant(Array.isArray(obj.vgrext), `${context}.vgrext: expected an array`);
81
+ invariant(obj.vgrext.length === 3, `${context}.vgrext: expected length 3`);
82
+ for (let i = 0; i < 3; i++) {
83
+ assertI32(obj.vgrext[i], `${context}.vgrext[${i}]`);
84
+ }
85
+ return obj;
86
+ }
87
+ /** Create a {@link DskApi} implementation backed by the native Node addon. */
88
+ export function createDskApi(native, handles) {
89
+ return {
90
+ dskobj: (dsk, bodids) => {
91
+ native.dskobj(dsk, bodids);
92
+ },
93
+ dsksrf: (dsk, bodyid, srfids) => {
94
+ native.dsksrf(dsk, bodyid, srfids);
95
+ },
96
+ dskgd: (handle, dladsc) => {
97
+ assertDlaDescriptor(dladsc, "dskgd(dladsc)");
98
+ const entry = handles.lookup(handle, DAS_BACKED, "dskgd");
99
+ return normalizeDskDescriptor(native.dskgd(entry.nativeHandle, dladsc), "dskgd()");
100
+ },
101
+ dskb02: (handle, dladsc) => {
102
+ assertDlaDescriptor(dladsc, "dskb02(dladsc)");
103
+ const entry = handles.lookup(handle, DAS_BACKED, "dskb02");
104
+ return normalizeDskType2Bookkeeping(native.dskb02(entry.nativeHandle, dladsc), "dskb02()");
105
+ },
106
+ };
107
+ }
108
+ //# sourceMappingURL=dsk.js.map
@@ -0,0 +1,10 @@
1
+ import { type EkApi } from "#backend-contract";
2
+ import type { NativeAddon } from "../runtime/addon.js";
3
+ import type { KernelStager } from "../runtime/kernel-staging.js";
4
+ import type { SpiceHandleRegistry } from "../runtime/spice-handles.js";
5
+ type NativeEkDeps = Pick<NativeAddon, "ekopr" | "ekopw" | "ekopn" | "ekcls" | "ekntab" | "ektnam" | "eknseg" | "ekfind" | "ekgc" | "ekgd" | "ekgi" | "ekifld" | "ekacli" | "ekacld" | "ekaclc" | "ekffld">;
6
+ type KernelStagerEkDeps = Pick<KernelStager, "resolvePath">;
7
+ /** Create an {@link EkApi} implementation backed by the native Node addon. */
8
+ export declare function createEkApi<N extends NativeEkDeps, S extends KernelStagerEkDeps | undefined>(native: N, handles: SpiceHandleRegistry, stager?: S): EkApi;
9
+ export {};
10
+ //# sourceMappingURL=ek.d.ts.map
@@ -0,0 +1,100 @@
1
+ import { assertSpiceInt32, assertSpiceInt32NonNegative, } from "#backend-contract";
2
+ import { invariant } from "#core";
3
+ const I32_MAX = 2147483647;
4
+ const EK_ONLY = ["EK"];
5
+ /** Create an {@link EkApi} implementation backed by the native Node addon. */
6
+ export function createEkApi(native, handles, stager) {
7
+ const registerEkHandle = (nativeHandle, context) => {
8
+ invariant(typeof nativeHandle === "number", `Expected native backend ${context} to return a number handle`);
9
+ assertSpiceInt32(nativeHandle, `native backend ${context} handle`);
10
+ return handles.register("EK", nativeHandle);
11
+ };
12
+ const resolvePath = (path) => {
13
+ if (!stager)
14
+ return path;
15
+ try {
16
+ return stager.resolvePath(path);
17
+ }
18
+ catch (error) {
19
+ // Best-effort path resolution for *virtual-ish* kernel IDs only. If this
20
+ // was an OS path (or some unexpected staging invariant), surface the error.
21
+ const isVirtualish = path.startsWith("kernels/") || path.startsWith("/kernels/");
22
+ if (!isVirtualish) {
23
+ throw error;
24
+ }
25
+ return path;
26
+ }
27
+ };
28
+ const api = {
29
+ ekopr: (path) => registerEkHandle(native.ekopr(resolvePath(path)), "ekopr(path)"),
30
+ ekopw: (path) => registerEkHandle(native.ekopw(resolvePath(path)), "ekopw(path)"),
31
+ ekopn: (path, ifname, ncomch) => {
32
+ assertSpiceInt32NonNegative(ncomch, "ekopn(ncomch)");
33
+ return registerEkHandle(native.ekopn(resolvePath(path), ifname, ncomch), "ekopn(path,ifname,ncomch)");
34
+ },
35
+ ekcls: (handle) => handles.close(handle, EK_ONLY, (e) => native.ekcls(e.nativeHandle), "ekcls"),
36
+ ekntab: () => {
37
+ const n = native.ekntab();
38
+ invariant(typeof n === "number" &&
39
+ Number.isInteger(n) &&
40
+ n >= 0 &&
41
+ n <= I32_MAX, "Expected native backend ekntab() to return a non-negative 32-bit signed integer");
42
+ return n;
43
+ },
44
+ ektnam: (n) => {
45
+ assertSpiceInt32NonNegative(n, "ektnam(n)");
46
+ const name = native.ektnam(n);
47
+ invariant(typeof name === "string", "Expected native backend ektnam(n) to return a string");
48
+ return name;
49
+ },
50
+ eknseg: (handle) => {
51
+ const nseg = native.eknseg(handles.lookup(handle, EK_ONLY, "eknseg").nativeHandle);
52
+ invariant(typeof nseg === "number" &&
53
+ Number.isInteger(nseg) &&
54
+ nseg >= 0 &&
55
+ nseg <= I32_MAX, "Expected native backend eknseg(handle) to return a non-negative 32-bit signed integer");
56
+ return nseg;
57
+ },
58
+ ekfind: (query) => native.ekfind(query),
59
+ ekgc: (selidx, row, elment) => {
60
+ assertSpiceInt32NonNegative(selidx, "ekgc(selidx)");
61
+ assertSpiceInt32NonNegative(row, "ekgc(row)");
62
+ assertSpiceInt32NonNegative(elment, "ekgc(elment)");
63
+ return native.ekgc(selidx, row, elment);
64
+ },
65
+ ekgd: (selidx, row, elment) => {
66
+ assertSpiceInt32NonNegative(selidx, "ekgd(selidx)");
67
+ assertSpiceInt32NonNegative(row, "ekgd(row)");
68
+ assertSpiceInt32NonNegative(elment, "ekgd(elment)");
69
+ return native.ekgd(selidx, row, elment);
70
+ },
71
+ ekgi: (selidx, row, elment) => {
72
+ assertSpiceInt32NonNegative(selidx, "ekgi(selidx)");
73
+ assertSpiceInt32NonNegative(row, "ekgi(row)");
74
+ assertSpiceInt32NonNegative(elment, "ekgi(elment)");
75
+ return native.ekgi(selidx, row, elment);
76
+ },
77
+ ekifld: (handle, tabnam, nrows, cnames, decls) => {
78
+ assertSpiceInt32(nrows, "ekifld(nrows)", { min: 1 });
79
+ return native.ekifld(handles.lookup(handle, EK_ONLY, "ekifld").nativeHandle, tabnam, nrows, cnames, decls);
80
+ },
81
+ ekacli: (handle, segno, column, ivals, entszs, nlflgs, rcptrs) => {
82
+ assertSpiceInt32NonNegative(segno, "ekacli(segno)");
83
+ native.ekacli(handles.lookup(handle, EK_ONLY, "ekacli").nativeHandle, segno, column, ivals, entszs, nlflgs, rcptrs);
84
+ },
85
+ ekacld: (handle, segno, column, dvals, entszs, nlflgs, rcptrs) => {
86
+ assertSpiceInt32NonNegative(segno, "ekacld(segno)");
87
+ native.ekacld(handles.lookup(handle, EK_ONLY, "ekacld").nativeHandle, segno, column, dvals, entszs, nlflgs, rcptrs);
88
+ },
89
+ ekaclc: (handle, segno, column, cvals, entszs, nlflgs, rcptrs) => {
90
+ assertSpiceInt32NonNegative(segno, "ekaclc(segno)");
91
+ native.ekaclc(handles.lookup(handle, EK_ONLY, "ekaclc").nativeHandle, segno, column, cvals, entszs, nlflgs, rcptrs);
92
+ },
93
+ ekffld: (handle, segno, rcptrs) => {
94
+ assertSpiceInt32NonNegative(segno, "ekffld(segno)");
95
+ native.ekffld(handles.lookup(handle, EK_ONLY, "ekffld").nativeHandle, segno, rcptrs);
96
+ },
97
+ };
98
+ return api;
99
+ }
100
+ //# sourceMappingURL=ek.js.map
@@ -1,4 +1,8 @@
1
1
  import type { EphemerisApi } from "#backend-contract";
2
2
  import type { NativeAddon } from "../runtime/addon.js";
3
- export declare function createEphemerisApi(native: NativeAddon): EphemerisApi;
3
+ import type { KernelStager } from "../runtime/kernel-staging.js";
4
+ import type { SpiceHandleRegistry } from "../runtime/spice-handles.js";
5
+ import type { VirtualOutputStager } from "../runtime/virtual-output-staging.js";
6
+ /** Create an {@link EphemerisApi} implementation backed by the native Node addon. */
7
+ export declare function createEphemerisApi(native: NativeAddon, handles: SpiceHandleRegistry, stager: KernelStager, outputs: VirtualOutputStager): EphemerisApi;
4
8
  //# sourceMappingURL=ephemeris.d.ts.map
@@ -1,5 +1,29 @@
1
1
  import { invariant } from "#core";
2
- export function createEphemerisApi(native) {
2
+ const I32_MAX = 2147483647;
3
+ function assertSpkPackedDescriptor(out, label) {
4
+ invariant(Array.isArray(out) && out.length === 5, `Expected ${label} to be a length-5 array`);
5
+ for (let i = 0; i < 5; i++) {
6
+ const v = out[i];
7
+ invariant(typeof v === "number" && Number.isFinite(v), `Expected ${label}[${i}] to be a finite number`);
8
+ }
9
+ }
10
+ function isVirtualOutput(value) {
11
+ return (typeof value === "object" &&
12
+ value !== null &&
13
+ value.kind === "virtual-output" &&
14
+ typeof value.path === "string");
15
+ }
16
+ function resolveSpkPath(outputs, file, context) {
17
+ if (typeof file === "string") {
18
+ return file;
19
+ }
20
+ // Be defensive: callers can cast.
21
+ invariant(isVirtualOutput(file), `${context}: expected VirtualOutput {kind:'virtual-output', path:string}`);
22
+ return outputs.resolvePathForSpice(file);
23
+ }
24
+ /** Create an {@link EphemerisApi} implementation backed by the native Node addon. */
25
+ export function createEphemerisApi(native, handles, stager, outputs) {
26
+ const virtualOutputByHandle = new Map();
3
27
  return {
4
28
  spkezr: (target, et, ref, abcorr, observer) => {
5
29
  const out = native.spkezr(target, et, ref, abcorr, observer);
@@ -19,6 +43,131 @@ export function createEphemerisApi(native) {
19
43
  const result = { pos, lt: out.lt };
20
44
  return result;
21
45
  },
46
+ spkez: (target, et, ref, abcorr, observer) => {
47
+ const out = native.spkez(target, et, ref, abcorr, observer);
48
+ invariant(out && typeof out === "object", "Expected spkez() to return an object");
49
+ invariant(Array.isArray(out.state) && out.state.length === 6, "Expected spkez().state to be a length-6 array");
50
+ invariant(typeof out.lt === "number", "Expected spkez().lt to be a number");
51
+ const state = out.state;
52
+ const result = { state, lt: out.lt };
53
+ return result;
54
+ },
55
+ spkezp: (target, et, ref, abcorr, observer) => {
56
+ const out = native.spkezp(target, et, ref, abcorr, observer);
57
+ invariant(out && typeof out === "object", "Expected spkezp() to return an object");
58
+ invariant(Array.isArray(out.pos) && out.pos.length === 3, "Expected spkezp().pos to be a length-3 array");
59
+ invariant(typeof out.lt === "number", "Expected spkezp().lt to be a number");
60
+ const pos = out.pos;
61
+ const result = { pos, lt: out.lt };
62
+ return result;
63
+ },
64
+ spkgeo: (target, et, ref, observer) => {
65
+ const out = native.spkgeo(target, et, ref, observer);
66
+ invariant(out && typeof out === "object", "Expected spkgeo() to return an object");
67
+ invariant(Array.isArray(out.state) && out.state.length === 6, "Expected spkgeo().state to be a length-6 array");
68
+ invariant(typeof out.lt === "number", "Expected spkgeo().lt to be a number");
69
+ const state = out.state;
70
+ const result = { state, lt: out.lt };
71
+ return result;
72
+ },
73
+ spkgps: (target, et, ref, observer) => {
74
+ const out = native.spkgps(target, et, ref, observer);
75
+ invariant(out && typeof out === "object", "Expected spkgps() to return an object");
76
+ invariant(Array.isArray(out.pos) && out.pos.length === 3, "Expected spkgps().pos to be a length-3 array");
77
+ invariant(typeof out.lt === "number", "Expected spkgps().lt to be a number");
78
+ const pos = out.pos;
79
+ const result = { pos, lt: out.lt };
80
+ return result;
81
+ },
82
+ spkssb: (target, et, ref) => {
83
+ const out = native.spkssb(target, et, ref);
84
+ invariant(Array.isArray(out) && out.length === 6, "Expected spkssb() to return a length-6 array");
85
+ return out;
86
+ },
87
+ spkcov: (spk, idcode, cover) => {
88
+ const resolved = stager.resolvePathForSpice(spk);
89
+ native.spkcov(resolved, idcode, cover);
90
+ },
91
+ spkobj: (spk, ids) => {
92
+ const resolved = stager.resolvePathForSpice(spk);
93
+ native.spkobj(resolved, ids);
94
+ },
95
+ spksfs: (body, et) => {
96
+ const out = native.spksfs(body, et);
97
+ invariant(out && typeof out === "object", "Expected spksfs() to return an object");
98
+ invariant(typeof out.found === "boolean", "Expected spksfs().found to be a boolean");
99
+ if (!out.found) {
100
+ return { found: false };
101
+ }
102
+ invariant(typeof out.handle === "number", "Expected spksfs().handle to be a number when found");
103
+ const descr = out.descr;
104
+ assertSpkPackedDescriptor(descr, "spksfs().descr");
105
+ invariant(typeof out.ident === "string", "Expected spksfs().ident to be a string when found");
106
+ return {
107
+ found: true,
108
+ handle: out.handle,
109
+ descr,
110
+ ident: out.ident,
111
+ };
112
+ },
113
+ spkpds: (body, center, frame, type, first, last) => {
114
+ const out = native.spkpds(body, center, frame, type, first, last);
115
+ assertSpkPackedDescriptor(out, "spkpds() output");
116
+ return out;
117
+ },
118
+ spkuds: (descr) => {
119
+ const out = native.spkuds(descr);
120
+ invariant(out && typeof out === "object", "Expected spkuds() to return an object");
121
+ const obj = out;
122
+ const keys = ["body", "center", "frame", "type", "first", "last", "baddr", "eaddr"];
123
+ for (const k of keys) {
124
+ invariant(typeof obj[k] === "number", `Expected spkuds().${k} to be a number`);
125
+ }
126
+ return out;
127
+ },
128
+ // --- SPK writers -------------------------------------------------------
129
+ spkopn: (file, ifname, ncomch) => {
130
+ const path = resolveSpkPath(outputs, file, "spkopn(file)");
131
+ const nativeHandle = native.spkopn(path, ifname, ncomch);
132
+ const handle = handles.register("SPK", nativeHandle);
133
+ if (typeof file !== "string") {
134
+ // `resolveSpkPath` already validated, but be defensive: callers can cast.
135
+ invariant(isVirtualOutput(file), "spkopn(file): expected VirtualOutput {kind:'virtual-output', path:string}");
136
+ const out = { kind: "virtual-output", path: file.path };
137
+ outputs.markOpen(out);
138
+ virtualOutputByHandle.set(handle, out);
139
+ }
140
+ return handle;
141
+ },
142
+ spkopa: (file) => {
143
+ const path = resolveSpkPath(outputs, file, "spkopa(file)");
144
+ const nativeHandle = native.spkopa(path);
145
+ const handle = handles.register("SPK", nativeHandle);
146
+ if (typeof file !== "string") {
147
+ invariant(isVirtualOutput(file), "spkopa(file): expected VirtualOutput {kind:'virtual-output', path:string}");
148
+ const out = { kind: "virtual-output", path: file.path };
149
+ outputs.markOpen(out);
150
+ virtualOutputByHandle.set(handle, out);
151
+ }
152
+ return handle;
153
+ },
154
+ spkcls: (handle) => {
155
+ const out = virtualOutputByHandle.get(handle);
156
+ handles.close(handle, ["SPK"], (e) => native.spkcls(e.nativeHandle), "spkcls");
157
+ if (out) {
158
+ outputs.markClosed(out);
159
+ virtualOutputByHandle.delete(handle);
160
+ }
161
+ },
162
+ spkw08: (handle, body, center, frame, first, last, segid, degree, states, epoch1, step) => {
163
+ invariant(Array.isArray(states) || states instanceof Float64Array, "spkw08(states): expected number[] or Float64Array");
164
+ invariant(states.length % 6 === 0, "spkw08(): expected states.length to be a multiple of 6");
165
+ invariant(states.length > 0, "spkw08(): expected at least one state record");
166
+ const n = states.length / 6;
167
+ invariant(Number.isSafeInteger(n) && n > 0 && n <= I32_MAX, `spkw08(): expected states.length/6 to be a 32-bit signed integer (got n=${n})`);
168
+ const nativeHandle = handles.lookup(handle, ["SPK"], "spkw08").nativeHandle;
169
+ native.spkw08(nativeHandle, body, center, frame, first, last, segid, degree, states, epoch1, step);
170
+ },
22
171
  };
23
172
  }
24
173
  //# sourceMappingURL=ephemeris.js.map
@@ -0,0 +1,5 @@
1
+ import { type ErrorApi } from "#backend-contract";
2
+ import type { NativeAddon } from "../runtime/addon.js";
3
+ /** Create an {@link ErrorApi} implementation backed by the native Node addon. */
4
+ export declare function createErrorApi(native: NativeAddon): ErrorApi;
5
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1,34 @@
1
+ import { assertGetmsgWhich } from "#backend-contract";
2
+ import { invariant } from "#core";
3
+ /** Create an {@link ErrorApi} implementation backed by the native Node addon. */
4
+ export function createErrorApi(native) {
5
+ return {
6
+ failed: () => {
7
+ const out = native.failed();
8
+ invariant(typeof out === "boolean", "Expected native backend failed() to return a boolean");
9
+ return out;
10
+ },
11
+ reset: () => {
12
+ native.reset();
13
+ },
14
+ getmsg: (which) => {
15
+ assertGetmsgWhich(which);
16
+ const out = native.getmsg(which);
17
+ invariant(typeof out === "string", "Expected native backend getmsg() to return a string");
18
+ return out;
19
+ },
20
+ setmsg: (message) => {
21
+ native.setmsg(message);
22
+ },
23
+ sigerr: (short) => {
24
+ native.sigerr(short);
25
+ },
26
+ chkin: (name) => {
27
+ native.chkin(name);
28
+ },
29
+ chkout: (name) => {
30
+ native.chkout(name);
31
+ },
32
+ };
33
+ }
34
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1,7 @@
1
+ import type { FileIoApi } from "#backend-contract";
2
+ import type { NativeAddon } from "../runtime/addon.js";
3
+ import type { VirtualOutputStager } from "../runtime/virtual-output-staging.js";
4
+ import type { SpiceHandleRegistry } from "../runtime/spice-handles.js";
5
+ /** Create a {@link FileIoApi} implementation backed by the native Node addon. */
6
+ export declare function createFileIoApi(native: NativeAddon, handles: SpiceHandleRegistry, outputs: VirtualOutputStager): FileIoApi;
7
+ //# sourceMappingURL=file-io.d.ts.map
@@ -0,0 +1,105 @@
1
+ import { invariant } from "#core";
2
+ const I32_MIN = -2147483648;
3
+ const I32_MAX = 2147483647;
4
+ const DAS_BACKED = ["DAS", "DLA"];
5
+ function assertDlaDescriptor(value, context) {
6
+ invariant(typeof value === "object" && value !== null, `${context}: expected an object`);
7
+ const obj = value;
8
+ for (const key of [
9
+ "bwdptr",
10
+ "fwdptr",
11
+ "ibase",
12
+ "isize",
13
+ "dbase",
14
+ "dsize",
15
+ "cbase",
16
+ "csize",
17
+ ]) {
18
+ const v = obj[key];
19
+ invariant(typeof v === "number" &&
20
+ Number.isInteger(v) &&
21
+ v >= I32_MIN &&
22
+ v <= I32_MAX, `${context}: expected ${key} to be a 32-bit signed integer`);
23
+ const min = key === "bwdptr" || key === "fwdptr" ? -1 : 0;
24
+ invariant(v >= min, `${context}: expected ${key} to be >= ${min}`);
25
+ }
26
+ }
27
+ function normalizeFoundDlaDescriptor(value, context) {
28
+ invariant(typeof value === "object" && value !== null, `${context}: expected an object`);
29
+ const obj = value;
30
+ invariant(typeof obj.found === "boolean", `${context}: expected found to be a boolean`);
31
+ if (!obj.found) {
32
+ return { found: false };
33
+ }
34
+ assertDlaDescriptor(obj.descr, `${context}.descr`);
35
+ return { found: true, descr: obj.descr };
36
+ }
37
+ /** Create a {@link FileIoApi} implementation backed by the native Node addon. */
38
+ export function createFileIoApi(native, handles, outputs) {
39
+ function closeDasBacked(handle, context) {
40
+ handles.close(handle, DAS_BACKED, (entry) => {
41
+ // In CSPICE, `dascls_c` closes both DAS and DLA handles, and `dlacls_c`
42
+ // is just an alias.
43
+ native.dascls(entry.nativeHandle);
44
+ }, context);
45
+ }
46
+ const api = {
47
+ exists: (path) => {
48
+ const exists = native.exists(path);
49
+ invariant(typeof exists === "boolean", "Expected native backend exists() to return a boolean");
50
+ return exists;
51
+ },
52
+ getfat: (path) => {
53
+ const result = native.getfat(path);
54
+ invariant(typeof result === "object" && result !== null, "Expected native backend getfat() to return an object");
55
+ const obj = result;
56
+ invariant(typeof obj.arch === "string", "Expected getfat().arch to be a string");
57
+ invariant(typeof obj.type === "string", "Expected getfat().type to be a string");
58
+ return { arch: obj.arch, type: obj.type };
59
+ },
60
+ readVirtualOutput: (output) => {
61
+ invariant(output && typeof output === "object", "readVirtualOutput(output): expected an object");
62
+ const obj = output;
63
+ invariant(obj.kind === "virtual-output", "readVirtualOutput(output): expected kind='virtual-output'");
64
+ invariant(typeof obj.path === "string", "readVirtualOutput(output): expected path to be a string");
65
+ return outputs.readVirtualOutput({ kind: "virtual-output", path: obj.path });
66
+ },
67
+ dafopr: (path) => handles.register("DAF", native.dafopr(path)),
68
+ dafcls: (handle) => handles.close(handle, ["DAF"], (e) => native.dafcls(e.nativeHandle), "dafcls"),
69
+ dafbfs: (handle) => native.dafbfs(handles.lookup(handle, ["DAF"], "dafbfs").nativeHandle),
70
+ daffna: (handle) => {
71
+ const found = native.daffna(handles.lookup(handle, ["DAF"], "daffna").nativeHandle);
72
+ invariant(typeof found === "boolean", "Expected native backend daffna() to return a boolean");
73
+ return found;
74
+ },
75
+ dasopr: (path) => handles.register("DAS", native.dasopr(path)),
76
+ dascls: (handle) => closeDasBacked(handle, "dascls"),
77
+ dlaopn: (path, ftype, ifname, ncomch) => handles.register("DLA", native.dlaopn(path, ftype, ifname, ncomch)),
78
+ dlabfs: (handle) => normalizeFoundDlaDescriptor(native.dlabfs(handles.lookup(handle, DAS_BACKED, "dlabfs").nativeHandle), "dlabfs()"),
79
+ dlafns: (handle, descr) => {
80
+ assertDlaDescriptor(descr, "dlafns(descr)");
81
+ return normalizeFoundDlaDescriptor(native.dlafns(handles.lookup(handle, DAS_BACKED, "dlafns").nativeHandle, descr), "dlafns()");
82
+ },
83
+ dlacls: (handle) => closeDasBacked(handle, "dlacls"),
84
+ dskopn: (path, ifname, ncomch) =>
85
+ // DSKs are DAS-backed; register as DAS so `dascls` can close it.
86
+ handles.register("DAS", native.dskopn(path, ifname, ncomch)),
87
+ dskmi2: (nv, vrtces, np, plates, finscl, corscl, worksz, voxpsz, voxlsz, makvtl, spxisz) => {
88
+ const result = native.dskmi2(nv, vrtces, np, plates, finscl, corscl, worksz, voxpsz, voxlsz, makvtl, spxisz);
89
+ invariant(typeof result === "object" && result !== null, "Expected native backend dskmi2() to return an object");
90
+ const obj = result;
91
+ invariant(Array.isArray(obj.spaixd), "Expected dskmi2().spaixd to be an array");
92
+ invariant(Array.isArray(obj.spaixi), "Expected dskmi2().spaixi to be an array");
93
+ invariant(obj.spaixd.every((v) => typeof v === "number"), "Expected dskmi2().spaixd to be a number[]");
94
+ invariant(obj.spaixi.every((v) => typeof v === "number"), "Expected dskmi2().spaixi to be a number[]");
95
+ return { spaixd: obj.spaixd, spaixi: obj.spaixi };
96
+ },
97
+ dskw02: (handle, center, surfid, dclass, frame, corsys, corpar, mncor1, mxcor1, mncor2, mxcor2, mncor3, mxcor3, first, last, nv, vrtces, np, plates, spaixd, spaixi) => native.dskw02(handles.lookup(handle, ["DAS"], "dskw02").nativeHandle, center, surfid, dclass, frame, corsys, corpar, mncor1, mxcor1, mncor2, mxcor2, mncor3, mxcor3, first, last, nv, vrtces, np, plates, spaixd, spaixi),
98
+ };
99
+ Object.defineProperty(api, "__debugOpenHandleCount", {
100
+ value: () => handles.size(),
101
+ enumerable: false,
102
+ });
103
+ return api;
104
+ }
105
+ //# sourceMappingURL=file-io.js.map
@@ -1,4 +1,5 @@
1
1
  import type { FramesApi } from "#backend-contract";
2
2
  import type { NativeAddon } from "../runtime/addon.js";
3
+ /** Create a {@link FramesApi} implementation backed by the native Node addon. */
3
4
  export declare function createFramesApi(native: NativeAddon): FramesApi;
4
5
  //# sourceMappingURL=frames.d.ts.map
@@ -1,4 +1,21 @@
1
+ import { brandMat3RowMajor } from "#backend-contract";
1
2
  import { invariant } from "#core";
3
+ const UINT32_MAX = 0xffff_ffff;
4
+ // Opaque cell/window handles are represented as branded numbers in the backend
5
+ // contract, but we still validate them at runtime to keep error behavior
6
+ // consistent across backends (mirrors the WASM handle assertions).
7
+ function assertOpaqueHandle(handle, context) {
8
+ if (typeof handle !== "number" || !Number.isFinite(handle) || !Number.isInteger(handle)) {
9
+ throw new TypeError(`${context}: expected handle to be an integer number (got ${handle})`);
10
+ }
11
+ if (handle <= 0) {
12
+ throw new RangeError(`${context}: expected handle to be > 0 (got ${handle})`);
13
+ }
14
+ if (!Number.isSafeInteger(handle) || handle > UINT32_MAX) {
15
+ throw new RangeError(`${context}: expected handle to be a non-zero uint32 (got ${handle})`);
16
+ }
17
+ }
18
+ /** Create a {@link FramesApi} implementation backed by the native Node addon. */
2
19
  export function createFramesApi(native) {
3
20
  return {
4
21
  namfrm: (name) => {
@@ -35,34 +52,69 @@ export function createFramesApi(native) {
35
52
  invariant(typeof out.frname === "string", "Expected cnmfrm().frname to be a string");
36
53
  return { found: true, frcode: out.frcode, frname: out.frname };
37
54
  },
55
+ frinfo: (frameId) => {
56
+ const out = native.frinfo(frameId);
57
+ if (!out.found) {
58
+ return { found: false };
59
+ }
60
+ invariant(typeof out.center === "number", "Expected frinfo().center to be a number");
61
+ invariant(typeof out.frameClass === "number", "Expected frinfo().frameClass to be a number");
62
+ invariant(typeof out.classId === "number", "Expected frinfo().classId to be a number");
63
+ return { found: true, center: out.center, frameClass: out.frameClass, classId: out.classId };
64
+ },
65
+ ccifrm: (frameClass, classId) => {
66
+ const out = native.ccifrm(frameClass, classId);
67
+ if (!out.found) {
68
+ return { found: false };
69
+ }
70
+ invariant(typeof out.frcode === "number", "Expected ccifrm().frcode to be a number");
71
+ invariant(typeof out.frname === "string", "Expected ccifrm().frname to be a string");
72
+ invariant(typeof out.center === "number", "Expected ccifrm().center to be a number");
73
+ return { found: true, frcode: out.frcode, frname: out.frname, center: out.center };
74
+ },
38
75
  ckgp: (inst, sclkdp, tol, ref) => {
39
76
  const out = native.ckgp(inst, sclkdp, tol, ref);
40
77
  if (!out.found) {
41
78
  return { found: false };
42
79
  }
43
- invariant(Array.isArray(out.cmat) && out.cmat.length === 9, "Expected ckgp().cmat to be a length-9 array");
80
+ const cmat = brandMat3RowMajor(out.cmat, { label: "ckgp().cmat" });
44
81
  invariant(typeof out.clkout === "number", "Expected ckgp().clkout to be a number");
45
- return { found: true, cmat: out.cmat, clkout: out.clkout };
82
+ return { found: true, cmat, clkout: out.clkout };
46
83
  },
47
84
  ckgpav: (inst, sclkdp, tol, ref) => {
48
85
  const out = native.ckgpav(inst, sclkdp, tol, ref);
49
86
  if (!out.found) {
50
87
  return { found: false };
51
88
  }
52
- invariant(Array.isArray(out.cmat) && out.cmat.length === 9, "Expected ckgpav().cmat to be a length-9 array");
89
+ const cmat = brandMat3RowMajor(out.cmat, { label: "ckgpav().cmat" });
53
90
  invariant(Array.isArray(out.av) && out.av.length === 3, "Expected ckgpav().av to be a length-3 array");
54
91
  invariant(typeof out.clkout === "number", "Expected ckgpav().clkout to be a number");
55
92
  return {
56
93
  found: true,
57
- cmat: out.cmat,
94
+ cmat,
58
95
  av: out.av,
59
96
  clkout: out.clkout,
60
97
  };
61
98
  },
99
+ cklpf: (ck) => {
100
+ const handle = native.cklpf(ck);
101
+ invariant(typeof handle === "number" && Number.isInteger(handle), "Expected cklpf() to return an integer handle");
102
+ return handle;
103
+ },
104
+ ckupf: (handle) => {
105
+ native.ckupf(handle);
106
+ },
107
+ ckobj: (ck, ids) => {
108
+ assertOpaqueHandle(ids, "ckobj(ids)");
109
+ native.ckobj(ck, ids);
110
+ },
111
+ ckcov: (ck, idcode, needav, level, tol, timsys, cover) => {
112
+ assertOpaqueHandle(cover, "ckcov(cover)");
113
+ native.ckcov(ck, idcode, needav, level, tol, timsys, cover);
114
+ },
62
115
  pxform: (from, to, et) => {
63
116
  const m = native.pxform(from, to, et);
64
- invariant(Array.isArray(m) && m.length === 9, "Expected pxform() to return a length-9 array");
65
- return m;
117
+ return brandMat3RowMajor(m, { label: "pxform()" });
66
118
  },
67
119
  sxform: (from, to, et) => {
68
120
  const m = native.sxform(from, to, et);