@unyt/datex 0.0.13 → 0.0.15

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 (147) hide show
  1. package/esm/datex-web/datex_web.d.ts +93 -2
  2. package/esm/datex-web/datex_web.internal.d.ts +221 -188
  3. package/esm/datex-web/datex_web.internal.d.ts.map +1 -1
  4. package/esm/datex-web/datex_web.internal.js +453 -385
  5. package/esm/datex-web/datex_web.wasm +0 -0
  6. package/esm/datex-web/types/decompiler/options.d.ts +17 -0
  7. package/esm/datex-web/types/decompiler/options.d.ts.map +1 -0
  8. package/esm/datex-web/types/decompiler/options.js +4 -0
  9. package/esm/datex-web/types/disassembler/options.d.ts +6 -0
  10. package/esm/datex-web/types/disassembler/options.d.ts.map +1 -0
  11. package/esm/datex-web/types/disassembler/options.js +4 -0
  12. package/esm/datex-web/types/network/com_hub/managers/socket_manager.d.ts +9 -0
  13. package/esm/datex-web/types/network/com_hub/managers/socket_manager.d.ts.map +1 -0
  14. package/esm/datex-web/types/network/com_hub/managers/socket_manager.js +4 -0
  15. package/esm/datex-web/types/network/com_hub/metadata.d.ts +20 -0
  16. package/esm/datex-web/types/network/com_hub/metadata.d.ts.map +1 -0
  17. package/esm/datex-web/types/network/com_hub/metadata.js +4 -0
  18. package/esm/datex-web/types/network/com_hub/mod.d.ts +6 -0
  19. package/esm/datex-web/types/network/com_hub/mod.d.ts.map +1 -0
  20. package/esm/datex-web/types/network/com_hub/mod.js +4 -0
  21. package/esm/datex-web/types/network/com_hub/network_tracing.d.ts +23 -0
  22. package/esm/datex-web/types/network/com_hub/network_tracing.d.ts.map +1 -0
  23. package/esm/datex-web/types/network/com_hub/network_tracing.js +4 -0
  24. package/esm/datex-web/types/network/com_hub.d.ts +8 -0
  25. package/esm/datex-web/types/network/com_hub.d.ts.map +1 -0
  26. package/esm/datex-web/types/network/com_hub.js +4 -0
  27. package/esm/datex-web/types/network/com_interfaces/com_interface/properties.d.ts +27 -0
  28. package/esm/datex-web/types/network/com_interfaces/com_interface/properties.d.ts.map +1 -0
  29. package/esm/datex-web/types/network/com_interfaces/com_interface/properties.js +4 -0
  30. package/esm/datex-web/types/network/com_interfaces/default_setup_data/http_common.d.ts +10 -0
  31. package/esm/datex-web/types/network/com_interfaces/default_setup_data/http_common.d.ts.map +1 -0
  32. package/esm/datex-web/types/network/com_interfaces/default_setup_data/http_common.js +4 -0
  33. package/esm/datex-web/types/network/com_interfaces/default_setup_data/websocket/websocket_server.d.ts +6 -0
  34. package/esm/datex-web/types/network/com_interfaces/default_setup_data/websocket/websocket_server.d.ts.map +1 -0
  35. package/esm/datex-web/types/network/com_interfaces/default_setup_data/websocket/websocket_server.js +4 -0
  36. package/esm/datex-web/types/runtime/config.d.ts +16 -0
  37. package/esm/datex-web/types/runtime/config.d.ts.map +1 -0
  38. package/esm/datex-web/types/runtime/config.js +4 -0
  39. package/esm/default.d.ts.map +1 -1
  40. package/esm/default.js +2 -0
  41. package/esm/deno.json +73 -17
  42. package/esm/dif/core.d.ts +36 -39
  43. package/esm/dif/core.d.ts.map +1 -1
  44. package/esm/dif/core.js +33 -53
  45. package/esm/dif/dif-handler.d.ts +58 -101
  46. package/esm/dif/dif-handler.d.ts.map +1 -1
  47. package/esm/dif/dif-handler.js +417 -345
  48. package/esm/dif/display.d.ts +14 -5
  49. package/esm/dif/display.d.ts.map +1 -1
  50. package/esm/dif/display.js +89 -39
  51. package/esm/dif/helpers/mod.d.ts +6 -0
  52. package/esm/dif/helpers/mod.d.ts.map +1 -0
  53. package/esm/dif/helpers/mod.js +5 -0
  54. package/esm/dif/helpers/typed-integer.d.ts +14 -0
  55. package/esm/dif/helpers/typed-integer.d.ts.map +1 -0
  56. package/esm/dif/helpers/typed-integer.js +37 -0
  57. package/esm/dif/js-lib.d.ts +14 -1
  58. package/esm/dif/js-lib.d.ts.map +1 -1
  59. package/esm/dif/js-lib.js +19 -1
  60. package/esm/dif/mod.d.ts +2 -2
  61. package/esm/dif/mod.d.ts.map +1 -1
  62. package/esm/dif/mod.js +2 -2
  63. package/esm/dif/type-registry.d.ts +30 -21
  64. package/esm/dif/type-registry.d.ts.map +1 -1
  65. package/esm/dif/type-registry.js +45 -33
  66. package/esm/dif/types/mod.d.ts +9 -0
  67. package/esm/dif/types/mod.d.ts.map +1 -0
  68. package/esm/dif/types/mod.js +8 -0
  69. package/esm/dif/types/type.d.ts +91 -0
  70. package/esm/dif/types/type.d.ts.map +1 -0
  71. package/esm/dif/types/type.js +33 -0
  72. package/esm/dif/types/update.d.ts +63 -0
  73. package/esm/dif/types/update.d.ts.map +1 -0
  74. package/esm/dif/types/update.js +16 -0
  75. package/esm/dif/types/value.d.ts +62 -0
  76. package/esm/dif/types/value.d.ts.map +1 -0
  77. package/esm/dif/types/value.js +1 -0
  78. package/esm/dif/update.d.ts +20 -0
  79. package/esm/dif/update.d.ts.map +1 -0
  80. package/esm/dif/update.js +41 -0
  81. package/esm/dif/utils.d.ts +8 -0
  82. package/esm/dif/utils.d.ts.map +1 -0
  83. package/esm/dif/utils.js +67 -0
  84. package/esm/lib/js-core-types/array.d.ts +3 -0
  85. package/esm/lib/js-core-types/array.d.ts.map +1 -0
  86. package/esm/lib/js-core-types/array.js +175 -0
  87. package/esm/lib/js-core-types/map.d.ts +15 -0
  88. package/esm/lib/js-core-types/map.d.ts.map +1 -0
  89. package/esm/lib/js-core-types/map.js +88 -0
  90. package/esm/lib/js-core-types/mod.d.ts +8 -0
  91. package/esm/lib/js-core-types/mod.d.ts.map +1 -0
  92. package/esm/lib/js-core-types/mod.js +7 -0
  93. package/esm/lib/mod.d.ts +8 -0
  94. package/esm/lib/mod.d.ts.map +1 -0
  95. package/esm/lib/mod.js +7 -0
  96. package/esm/lib/special-core-types/endpoint.d.ts.map +1 -1
  97. package/esm/lib/special-core-types/mod.d.ts +9 -0
  98. package/esm/lib/special-core-types/mod.d.ts.map +1 -0
  99. package/esm/lib/special-core-types/mod.js +8 -0
  100. package/esm/lib/special-core-types/range.d.ts +26 -0
  101. package/esm/lib/special-core-types/range.d.ts.map +1 -0
  102. package/esm/lib/special-core-types/range.js +46 -0
  103. package/esm/lib/special-core-types/tagged.d.ts +17 -0
  104. package/esm/lib/special-core-types/tagged.d.ts.map +1 -0
  105. package/esm/lib/special-core-types/tagged.js +37 -0
  106. package/esm/lib/special-core-types/undefined.d.ts +7 -0
  107. package/esm/lib/special-core-types/undefined.d.ts.map +1 -0
  108. package/esm/lib/special-core-types/undefined.js +28 -0
  109. package/esm/mod.d.ts +3 -1
  110. package/esm/mod.d.ts.map +1 -1
  111. package/esm/mod.js +3 -1
  112. package/esm/network/com-hub.d.ts +28 -1
  113. package/esm/network/com-hub.d.ts.map +1 -1
  114. package/esm/network/com-hub.js +6 -2
  115. package/esm/network/interfaces/websocket-server-base.d.ts +1 -1
  116. package/esm/network/interfaces/websocket-server-base.d.ts.map +1 -1
  117. package/esm/network/interfaces/websocket-server-base.js +8 -7
  118. package/esm/network/interfaces/websocket-server-deno.d.ts +1 -1
  119. package/esm/network/interfaces/websocket-server-deno.d.ts.map +1 -1
  120. package/esm/repl/mod.d.ts +8 -0
  121. package/esm/repl/mod.d.ts.map +1 -0
  122. package/esm/repl/mod.js +31 -0
  123. package/esm/runtime/runtime.d.ts +43 -18
  124. package/esm/runtime/runtime.d.ts.map +1 -1
  125. package/esm/runtime/runtime.js +55 -32
  126. package/esm/{refs/ref.d.ts → shared-container/base-shared-container.d.ts} +13 -5
  127. package/esm/shared-container/base-shared-container.d.ts.map +1 -0
  128. package/esm/shared-container/base-shared-container.js +95 -0
  129. package/esm/shared-container/mod.d.ts +36 -0
  130. package/esm/shared-container/mod.d.ts.map +1 -0
  131. package/esm/shared-container/mod.js +29 -0
  132. package/esm/shared-container/owned.d.ts +33 -0
  133. package/esm/shared-container/owned.d.ts.map +1 -0
  134. package/esm/shared-container/owned.js +60 -0
  135. package/esm/shared-container/reference.d.ts +31 -0
  136. package/esm/shared-container/reference.d.ts.map +1 -0
  137. package/esm/shared-container/reference.js +64 -0
  138. package/esm/utils/devtools-formatter.js +24 -2
  139. package/esm/utils/option.d.ts +17 -0
  140. package/esm/utils/option.d.ts.map +1 -0
  141. package/esm/utils/option.js +54 -0
  142. package/package.json +1 -1
  143. package/esm/dif/definitions.d.ts +0 -134
  144. package/esm/dif/definitions.d.ts.map +0 -1
  145. package/esm/dif/definitions.js +0 -38
  146. package/esm/refs/ref.d.ts.map +0 -1
  147. package/esm/refs/ref.js +0 -60
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @module DIF Handler
3
+ * Represents the main interface for interacting with the DATEX Core via DIF from JavaScript.
4
+ */
1
5
  var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
6
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
7
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
@@ -10,13 +14,68 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
10
14
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
15
  };
12
16
  var _DIFHandler_runtime, _DIFHandler_handle, _DIFHandler_transceiver_id, _DIFHandler_cache, _DIFHandler_proxyMapping, _DIFHandler_referenceMetadata, _DIFHandler_observers, _DIFHandler_type_registry;
13
- import { Ref } from "../refs/ref.js";
14
17
  import { Endpoint } from "../lib/special-core-types/endpoint.js";
15
- import { DIFSharedValueMutability, DIFTypeDefinitionKind, DIFUpdateKind, } from "./definitions.js";
16
- import { CoreTypeAddress, CoreTypeAddressRanges } from "./core.js";
18
+ import { Range } from "../lib/special-core-types/range.js";
19
+ import { DIFUpdateKind, } from "./types/mod.js";
20
+ import { CoreLibTypeId } from "./core.js";
17
21
  import { TypeRegistry } from "./type-registry.js";
18
- import { panic } from "../utils/exceptions.js";
22
+ import { panic, unimplemented, unreachable } from "../utils/exceptions.js";
23
+ import { isJsUndefined, JS_UNDEFINED } from "../lib/special-core-types/undefined.js";
24
+ import { SharedContainerMutability } from "../shared-container/base-shared-container.js";
25
+ import { BaseSharedContainer } from "../shared-container/mod.js";
26
+ import { DIFSharedContainerOwnership } from "./types/type.js";
27
+ import { splitPointerAddressWithOwnership } from "../shared-container/mod.js";
28
+ import { combinePointerAddressWithOwnership } from "../shared-container/mod.js";
29
+ import { appendEntry, clear, deleteEntry, DIFPropertyKind, listSplice, replace, setEntry } from "./update.js";
30
+ import { createDIFProperty } from "./update.js";
19
31
  import { JsLibTypeAddress } from "./js-lib.js";
32
+ import { isJsMapTypeDefinition } from "../lib/mod.js";
33
+ import { OwnedSharedContainer } from "../shared-container/owned.js";
34
+ import { EMPTY_TAG, Tagged } from "../lib/special-core-types/tagged.js";
35
+ import { ibig } from "./helpers/mod.js";
36
+ /**
37
+ * Some DIF methods may return an optional ValueContainer, so does the execute_sync, when no result is returned.
38
+ * DIF must differentiate between null and no result, so we wrap DIFOptionalValueContainer.
39
+ * @param value - The DIFOptionalValueContainer to collapse.
40
+ * @returns The contained DIFValueContainer if present, or undefined if the value is not present.
41
+ */
42
+ function collapseDIFOption(value) {
43
+ if (value === null) {
44
+ return undefined;
45
+ }
46
+ else {
47
+ if (Array.isArray(value) && value.length === 1) {
48
+ return value[0];
49
+ }
50
+ else {
51
+ throw new Error("Invalid DIFOptionalValueContainer format: expected an array of length 1 or null");
52
+ }
53
+ }
54
+ }
55
+ /**
56
+ * Converts special float string representations ("nan", "infinity", "-infinity") to the JS values NaN, Infinity and -Infinity respectively.
57
+ * @param value - The string representation of the float value.
58
+ * @returns The corresponding JS number value for the special float representation.
59
+ * @throws If the input value is not a valid special float representation.
60
+ */
61
+ function specialDIFFloatToNumber(value) {
62
+ if (!isSpecialDIFFloatString(value)) {
63
+ throw new Error(`Expected a special float string ("nan", "infinity", "-infinity"), got ${value}`);
64
+ }
65
+ if (value === "nan") {
66
+ return NaN;
67
+ }
68
+ else if (value === "infinity") {
69
+ return Infinity;
70
+ }
71
+ else if (value === "-infinity") {
72
+ return -Infinity;
73
+ }
74
+ unreachable(`Invalid special float string: ${value}`);
75
+ }
76
+ function isSpecialDIFFloatString(value) {
77
+ return ["nan", "infinity", "-infinity"].includes(value);
78
+ }
20
79
  export const IS_PROXY_ACCESS = Symbol("IS_PROXY_ACCESS");
21
80
  /**
22
81
  * The DIFHandler class provides methods to interact with the DATEX Core DIF runtime,
@@ -33,7 +92,7 @@ export class DIFHandler {
33
92
  }
34
93
  /**
35
94
  * Internal property
36
- * @returns The RuntimeDIFHandle instance.
95
+ * @returns The {@link JSDIFInterface} instance.
37
96
  */
38
97
  get _handle() {
39
98
  return __classPrivateFieldGet(this, _DIFHandler_handle, "f");
@@ -51,7 +110,6 @@ export class DIFHandler {
51
110
  /**
52
111
  * Creates a new DIFHandler instance.
53
112
  * @param runtime - The JSRuntime instance for executing Datex scripts.
54
- * @param pointerCache - The PointerCache instance for managing object pointers. If not provided, a new PointerCache will be created.
55
113
  */
56
114
  constructor(runtime) {
57
115
  /** The JSRuntime interface for the underlying Datex Core runtime */
@@ -76,7 +134,7 @@ export class DIFHandler {
76
134
  _DIFHandler_observers.set(this, new Map());
77
135
  _DIFHandler_type_registry.set(this, new TypeRegistry(this));
78
136
  __classPrivateFieldSet(this, _DIFHandler_runtime, runtime, "f");
79
- __classPrivateFieldSet(this, _DIFHandler_handle, runtime.dif(), "f");
137
+ __classPrivateFieldSet(this, _DIFHandler_handle, runtime.dif_interface(), "f");
80
138
  }
81
139
  /**
82
140
  * Executes a Datex script asynchronously and returns a Promise that resolves to a DIFContainer.
@@ -85,8 +143,8 @@ export class DIFHandler {
85
143
  * @returns A Promise that resolves to the execution result as a DIFContainer.
86
144
  * @throws If an error occurs during execution.
87
145
  */
88
- executeDIF(datexScript, values = []) {
89
- return __classPrivateFieldGet(this, _DIFHandler_runtime, "f").execute(datexScript, this.convertToDIFValues(values));
146
+ async executeDIF(datexScript, values = []) {
147
+ return collapseDIFOption(await __classPrivateFieldGet(this, _DIFHandler_runtime, "f").execute(datexScript, this.convertToDIFValues(values)));
90
148
  }
91
149
  /**
92
150
  * Executes a Datex script synchronously and returns the result as a DIFContainer.
@@ -96,7 +154,7 @@ export class DIFHandler {
96
154
  * @throws If an error occurs during execution.
97
155
  */
98
156
  executeSyncDIF(datexScript, values = []) {
99
- return __classPrivateFieldGet(this, _DIFHandler_runtime, "f").execute_sync(datexScript, this.convertToDIFValues(values));
157
+ return collapseDIFOption(__classPrivateFieldGet(this, _DIFHandler_runtime, "f").execute_sync(datexScript, this.convertToDIFValues(values)));
100
158
  }
101
159
  /**
102
160
  * Creates a new shared value for the specified DIF value.
@@ -105,16 +163,23 @@ export class DIFHandler {
105
163
  * @param mutability - The mutability of the pointer.
106
164
  * @returns The created pointer address.
107
165
  */
108
- createSharedValueFromDIFValue(difValueContainer, allowedType = null, mutability) {
109
- return __classPrivateFieldGet(this, _DIFHandler_handle, "f").create_pointer(difValueContainer, allowedType, mutability);
166
+ constructSharedValue(difValueContainer, mutability = SharedContainerMutability.Mutable, allowedType = null) {
167
+ const baseSharedValueContainer = [
168
+ difValueContainer,
169
+ mutability,
170
+ ];
171
+ if (allowedType) {
172
+ baseSharedValueContainer[2] = allowedType;
173
+ }
174
+ return __classPrivateFieldGet(this, _DIFHandler_handle, "f").create_pointer(baseSharedValueContainer);
110
175
  }
111
176
  /**
112
177
  * Updates the DIF value at the specified address.
113
178
  * @param address - The address of the DIF value to update.
114
- * @param dif - The DIFUpdate object containing the update information.
179
+ * @param update_data - The DIFUpdate object containing the update information.
115
180
  */
116
- updateReference(address, dif) {
117
- __classPrivateFieldGet(this, _DIFHandler_handle, "f").update(__classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f"), address, dif);
181
+ updateSharedValue(address, update_data) {
182
+ return __classPrivateFieldGet(this, _DIFHandler_handle, "f").update(address, [__classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f"), ...update_data]);
118
183
  }
119
184
  /**
120
185
  * Registers an observer callback for changes to the DIF value at the specified address
@@ -127,8 +192,8 @@ export class DIFHandler {
127
192
  * @returns An observer ID that can be used to unregister the observer.
128
193
  * @throws If the pointer is final.
129
194
  */
130
- observePointerBindDirect(address, callback, options = { relay_own_updates: false }) {
131
- return __classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif().observe_pointer(__classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f"), address, options, callback);
195
+ observeSharedValueBindDirect(address, callback, options = { relay_own_updates: false }) {
196
+ return __classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif_interface().observe_pointer(__classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f"), address, options, callback);
132
197
  }
133
198
  /**
134
199
  * Updates the observe options for a registered observer.
@@ -137,7 +202,7 @@ export class DIFHandler {
137
202
  * @param options - The new observe options to apply.
138
203
  */
139
204
  updateObserverOptions(address, observerId, options) {
140
- __classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif().update_observer_options(address, observerId, options);
205
+ __classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif_interface().update_observer_options(address, observerId, options);
141
206
  }
142
207
  /**
143
208
  * Enables propagation of own updates for a registered observer.
@@ -166,8 +231,8 @@ export class DIFHandler {
166
231
  * @param address - The address of the DIF value being observed.
167
232
  * @param observerId - The observer ID returned by the observePointer method.
168
233
  */
169
- unobserveReferenceBindDirect(address, observerId) {
170
- __classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif().unobserve_pointer(address, observerId);
234
+ unobserveSharedValueBindDirect(address, observerId) {
235
+ __classPrivateFieldGet(this, _DIFHandler_runtime, "f").dif_interface().unobserve_pointer(address, observerId);
171
236
  }
172
237
  /**
173
238
  * Registers a local observer callback for changes to the DIF value at the specified address.
@@ -184,7 +249,7 @@ export class DIFHandler {
184
249
  let cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
185
250
  if (!cached) {
186
251
  // first resolve the pointer to make sure it's loaded in the cache
187
- this.resolvePointerAddressSync(address);
252
+ this.resolvePointerAddress(DIFSharedContainerOwnership.Immutable, address);
188
253
  cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
189
254
  }
190
255
  // make sure the pointer is not final (no observer)
@@ -235,131 +300,176 @@ export class DIFHandler {
235
300
  * @param value
236
301
  */
237
302
  resolveDIFValue(value) {
238
- let type = value.type;
239
- let convertMapToJSObject = false;
240
- // no type specified since it is inferable from the value
241
- if (type === undefined) {
242
- if (Array.isArray(value.value)) {
243
- // [[x,y,]] -> map
244
- if (Array.isArray(value.value[0])) {
245
- type = CoreTypeAddress.map;
246
- } // [x,y] or [] -> list
247
- else {
248
- type = CoreTypeAddress.list;
249
- }
303
+ // direct interpretation of trivial types without type annotation
304
+ if (value === null) {
305
+ return null;
306
+ }
307
+ else if (isJsUndefined(value)) {
308
+ return undefined;
309
+ }
310
+ else if (typeof value === "string") {
311
+ return value;
312
+ }
313
+ else if (typeof value === "boolean") {
314
+ return value;
315
+ }
316
+ else if (typeof value === "number") {
317
+ return value;
318
+ }
319
+ // custom interpretation means
320
+ if (!Array.isArray(value) || value.length < 2 || value.length > 3) {
321
+ console.log("value", value);
322
+ throw new Error("Invalid DIFValue format: expected an array for non-primitive types");
323
+ }
324
+ const [type, core, definition] = value;
325
+ let val = null;
326
+ if (type === CoreLibTypeId.null) {
327
+ if (core !== null) {
328
+ throw new Error("Expected null value for null type");
329
+ }
330
+ val = null;
331
+ }
332
+ else if (type === CoreLibTypeId.boolean) {
333
+ if (typeof core !== "boolean") {
334
+ throw new Error("Expected boolean value for boolean type");
335
+ }
336
+ val = core;
337
+ }
338
+ else if ([
339
+ CoreLibTypeId.integer_i8,
340
+ CoreLibTypeId.integer_i16,
341
+ CoreLibTypeId.integer_i32,
342
+ CoreLibTypeId.integer_u8,
343
+ CoreLibTypeId.integer_u16,
344
+ CoreLibTypeId.integer_u32,
345
+ CoreLibTypeId.integer_i64,
346
+ ].includes(type)) {
347
+ if (typeof core !== "number") {
348
+ throw new Error("Expected number value for integer type");
349
+ }
350
+ val = core;
351
+ }
352
+ else if (type === CoreLibTypeId.integer) {
353
+ if (typeof core === "string") {
354
+ val = parseInt(core, 10);
355
+ }
356
+ else
357
+ throw new Error("Expected number value for integer type");
358
+ }
359
+ else if ([
360
+ CoreLibTypeId.integer_i128,
361
+ CoreLibTypeId.integer_u64,
362
+ CoreLibTypeId.integer_u128,
363
+ CoreLibTypeId.integer_ibig,
364
+ ].includes(type)) {
365
+ if (typeof core !== "string" && typeof core !== "number") {
366
+ throw new Error("Expected string or number value for big integer type");
367
+ }
368
+ val = BigInt(core);
369
+ }
370
+ else if ([
371
+ CoreLibTypeId.decimal_dbig,
372
+ CoreLibTypeId.decimal, // FIXME rational notation 3/4
373
+ ].includes(type)) {
374
+ if (typeof core !== "string") {
375
+ throw new Error("Expected string value for decimal big type" + typeof core + " " + JSON.stringify(core));
376
+ }
377
+ if (isSpecialDIFFloatString(core)) {
378
+ val = specialDIFFloatToNumber(core);
379
+ } // FIXME this is a temporary solution until we have a proper decimal implementation
380
+ else if (core.includes("/")) {
381
+ const [numerator, denominator] = core.split("/").map((part) => part.trim());
382
+ val = parseFloat(numerator) / parseFloat(denominator);
383
+ }
384
+ else if (core.includes(".")) {
385
+ val = parseFloat(core);
250
386
  }
251
- else if (typeof value.value === "object" && value.value !== null) {
252
- type = CoreTypeAddress.map;
253
- convertMapToJSObject = true;
254
- } // primitive JS value, no type specified
255
387
  else {
256
- return value.value;
257
- }
258
- }
259
- // null, boolean and text types values are just returned as is
260
- if (type === CoreTypeAddress.boolean ||
261
- type == CoreTypeAddress.text ||
262
- type === CoreTypeAddress.null) {
263
- return value.value;
264
- } // small integers are interpreted as JS numbers
265
- else if (typeof type === "string" && (type == CoreTypeAddress.integer ||
266
- this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.small_signed_integers) ||
267
- this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.small_unsigned_integers))) {
268
- return Number(value.value);
269
- } // big integers are interpreted as JS BigInt
270
- else if (typeof type === "string" && (this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.big_signed_integers))) {
271
- return BigInt(value.value);
272
- } // decimal types are interpreted as JS numbers
273
- else if (typeof type === "string" &&
274
- this.isPointerAddressInAdresses(type, CoreTypeAddressRanges.decimals)) {
275
- return Number(value.value);
276
- } // endpoint types are resolved to Endpoint instances
277
- else if (type === CoreTypeAddress.endpoint) {
278
- return Endpoint.get(value.value);
279
- }
280
- else if (type === CoreTypeAddress.list) {
281
- return this.promiseAllOrSync(value.value.map((v) => this.resolveDIFValueContainer(v)));
282
- } // map types are resolved from a DIFObject (aka JS Map) or Array of key-value pairs to a JS object
283
- else if (type === CoreTypeAddress.map) {
284
- if (Array.isArray(value.value)) {
285
- const resolvedMap = new Map();
286
- for (const [key, val] of value.value) {
287
- resolvedMap.set(this.resolveDIFValueContainer(key), this.resolveDIFValueContainer(val));
288
- }
289
- // TODO: map promises
290
- return resolvedMap;
388
+ throw new Error("Expected a valid decimal string for decimal big type");
389
+ }
390
+ }
391
+ else if ([
392
+ CoreLibTypeId.decimal_f32,
393
+ CoreLibTypeId.decimal_f64,
394
+ ].includes(type)) {
395
+ if (typeof core === "string") {
396
+ val = specialDIFFloatToNumber(core);
397
+ }
398
+ else if (typeof core === "number") {
399
+ val = core;
291
400
  }
292
401
  else {
293
- if (convertMapToJSObject) {
294
- const resolvedObj = {};
295
- for (const [key, val] of Object.entries(value.value)) {
296
- resolvedObj[key] = this.resolveDIFValueContainer(val);
297
- }
298
- return resolvedObj;
299
- }
300
- else {
301
- const resolvedMap = new Map();
302
- for (const [key, val] of Object.entries(value.value)) {
303
- resolvedMap.set(key, this.resolveDIFValueContainer(val));
304
- }
305
- return resolvedMap;
306
- }
402
+ throw new Error("Expected number value for decimal type");
307
403
  }
308
- } // impl types
309
- else if (typeof type == "object" &&
310
- type.kind === DIFTypeDefinitionKind.ImplType) {
311
- // undefined (null + js.undefined)
312
- if (type.def[0] === CoreTypeAddress.null &&
313
- type.def[1].length === 1 &&
314
- type.def[1][0] == JsLibTypeAddress.undefined) {
315
- return undefined;
404
+ }
405
+ else if (type === CoreLibTypeId.text) {
406
+ if (typeof core !== "string") {
407
+ throw new Error("Expected string value for text type");
316
408
  }
409
+ val = core;
317
410
  }
318
- // custom types not implemented yet
319
- throw new Error("Custom type resolution not implemented yet");
320
- }
321
- /**
322
- * Converts an array of Promises or resolved values to either a Promise of an array of resolved values,
323
- * or an array of resolved values if all values are already resolved.
324
- */
325
- promiseAllOrSync(values) {
326
- if (values.some((v) => v instanceof Promise)) {
327
- return Promise.all(values);
411
+ else if (type === CoreLibTypeId.endpoint) {
412
+ if (typeof core !== "string") {
413
+ throw new Error("Expected string value for endpoint type");
414
+ }
415
+ val = Endpoint.get(core);
328
416
  }
329
- else {
330
- return values;
417
+ else if (type === CoreLibTypeId.Range) {
418
+ if (!Array.isArray(core) || core.length !== 2) {
419
+ throw new Error("Expected array of length 2 for range type");
420
+ }
421
+ const [start, end] = core;
422
+ const res = [
423
+ this.resolveDIFValueContainer(start),
424
+ this.resolveDIFValueContainer(end),
425
+ ];
426
+ // FIXME fix range
427
+ val = new Range(res[0], res[1]);
428
+ }
429
+ else if (type === CoreLibTypeId.List) {
430
+ if (!Array.isArray(core)) {
431
+ throw new Error("Expected array value for list type");
432
+ }
433
+ val = core.map((v) => this.resolveDIFValueContainer(v));
331
434
  }
332
- }
333
- /**
334
- * Converts an object with values that may be Promises to either a Promise of an object with resolved values,
335
- * or an object with resolved values if all values are already resolved.
336
- */
337
- promiseFromObjectOrSync(values) {
338
- const valueArray = Object.values(values);
339
- if (valueArray.some((v) => v instanceof Promise)) {
340
- return Promise.all(valueArray).then((resolvedValues) => {
341
- const resolvedObj = {};
342
- let i = 0;
343
- for (const key of Object.keys(values)) {
344
- resolvedObj[key] = resolvedValues[i++];
435
+ else if (type === CoreLibTypeId.Map) {
436
+ if (Array.isArray(core)) {
437
+ const map = new Map();
438
+ for (const [key, value] of core) {
439
+ map.set(this.resolveDIFValueContainer(key), this.resolveDIFValueContainer(value));
345
440
  }
346
- return resolvedObj;
347
- });
348
- }
349
- else {
350
- return values;
351
- }
352
- }
353
- /**
354
- * Maps a value or Promise of a value to another value or Promise of a value using the provided onfulfilled function.
355
- */
356
- mapPromise(value, onfulfilled) {
357
- if (value instanceof Promise) {
358
- return value.then(onfulfilled);
441
+ val = map;
442
+ }
443
+ else if (typeof core === "object" && core !== null) {
444
+ const obj = {};
445
+ for (const [key, value] of Object.entries(core)) {
446
+ obj[key] = this.resolveDIFValueContainer(value);
447
+ }
448
+ val = obj;
449
+ if (definition && isJsMapTypeDefinition(definition)) {
450
+ val = new Map(Object.entries(obj));
451
+ }
452
+ }
453
+ else {
454
+ throw new Error("Expected array of key-value pairs or object for map type");
455
+ }
359
456
  }
360
- else {
361
- return onfulfilled(value);
457
+ // for tagged type definition, wrap in Tagged
458
+ if (definition && typeof definition === "object" && "tagged_type" in definition) {
459
+ const [tag, innerType] = definition.tagged_type;
460
+ // special case: empty tag
461
+ if (val === null && innerType === CoreLibTypeId.Unit) {
462
+ val = new Tagged(tag, EMPTY_TAG);
463
+ }
464
+ else {
465
+ // TODO: handle other innerTypes if not default type
466
+ val = new Tagged(tag, val);
467
+ }
362
468
  }
469
+ // FIXME custom type resolution not implemented yet, just return the core value for now
470
+ return val;
471
+ // custom types not implemented yet
472
+ // throw new Error("Custom type resolution not implemented yet");
363
473
  }
364
474
  /**
365
475
  * Resolves a DIFValueContainer (either a DIFValue or a pointer address) to its corresponding JS value.
@@ -369,41 +479,27 @@ export class DIFHandler {
369
479
  * @returns The resolved value as type T, or a Promise that resolves to type T.
370
480
  */
371
481
  resolveDIFValueContainer(value) {
372
- if (typeof value !== "string") {
373
- return this.resolveDIFValue(value);
482
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && "$" in value) {
483
+ return this.resolvePointerAddress(...splitPointerAddressWithOwnership(value.$));
374
484
  }
375
485
  else {
376
- return this.resolvePointerAddress(value);
377
- }
378
- }
379
- /**
380
- * Synchronous version of resolveDIFValueContainer.
381
- * This method can only be used if the value only contains pointer addresses that are already loaded in memory -
382
- * otherwise, use the asynchronous `resolveDIFValueContainer` method instead.
383
- * @param value - The DIFValueContainer to resolve.
384
- * @returns The resolved value as type T.
385
- * @throws If the resolution would require asynchronous operations.
386
- */
387
- resolveDIFValueContainerSync(value) {
388
- const result = this.resolveDIFValueContainer(value);
389
- if (result instanceof Promise) {
390
- throw new Error("resolveDIFValueContainerSync cannot return a Promise. Use resolveDIFValueContainer() instead.");
486
+ return this.resolveDIFValue(value);
391
487
  }
392
- return result;
393
488
  }
394
489
  /**
395
490
  * Resolves a DIFProperty to its corresponding JS value.
396
491
  */
397
- resolveDIFPropertySync(property) {
398
- if (property.kind === "text") {
399
- return property.value;
492
+ resolveDIFProperty(property) {
493
+ if (typeof property === "number") {
494
+ return property;
400
495
  }
401
- else if (property.kind === "index") {
402
- return property.value;
496
+ if (typeof property === "string") {
497
+ return property;
403
498
  }
404
- else {
405
- return this.resolveDIFValueContainerSync(property.value);
499
+ if (typeof property === "object" && property !== null && !Array.isArray(property) && "value" in property) {
500
+ return this.resolveDIFValueContainer(property.value);
406
501
  }
502
+ throw new Error("Invalid DIFProperty format");
407
503
  }
408
504
  /**
409
505
  * Resolves a pointer address to its corresponding JS value.
@@ -412,43 +508,33 @@ export class DIFHandler {
412
508
  * @param address - The pointer address to resolve.
413
509
  * @returns The resolved value as type T, or a Promise that resolves to type T.
414
510
  */
415
- resolvePointerAddress(address) {
511
+ resolvePointerAddress(ownership, address) {
512
+ const addressWithOwnership = combinePointerAddressWithOwnership(address, ownership);
416
513
  // check cache first
417
- const cached = this.getCachedReference(address);
418
- if (cached) {
419
- return cached;
514
+ const cached = this.getCachedStateForSharedContainer(address, ownership);
515
+ if (cached === "insufficient_ownership") {
516
+ // try to resolve with with upgraded owership if possible
517
+ if (!__classPrivateFieldGet(this, _DIFHandler_handle, "f").has_address_with_ownership(addressWithOwnership)) {
518
+ throw new Error(`Address ${address} not found in runtime with ownership ${ownership} or higher`);
519
+ }
520
+ __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address).maxOwnership = ownership;
521
+ const upgraded = this.getCachedStateForSharedContainer(address, ownership);
522
+ if (typeof upgraded === "string") {
523
+ unreachable(`Ownership assertion passed but cache still returns ${upgraded}`);
524
+ }
525
+ return upgraded;
420
526
  }
421
- // if not in cache, resolve from runtime
422
- const reference = __classPrivateFieldGet(this, _DIFHandler_handle, "f").resolve_pointer_address(address);
423
- return this.mapPromise(reference, (reference) => {
424
- const value = this.resolveDIFValueContainer(reference.value);
425
- return this.mapPromise(value, (v) => {
426
- // init pointer
427
- this.initReference(address, v, reference.mut, reference.allowed_type);
428
- return v;
429
- });
430
- });
431
- }
432
- /**
433
- * Resolves a pointer address to its corresponding JS value synchronously.
434
- * If the pointer address is not yet loaded in memory, it returns a Promise that resolves to the value.
435
- * Otherwise, it returns the resolved value directly.
436
- * @param address - The pointer address to resolve.
437
- * @returns The resolved value as type T, or a Promise that resolves to type T.
438
- * @throws If the resolution would require asynchronous operations.
439
- */
440
- resolvePointerAddressSync(address) {
441
- // check cache first
442
- const cached = this.getCachedReference(address);
443
- if (cached) {
527
+ else if (cached === "not_cached") {
528
+ // if not in cache, resolve from runtime
529
+ const base = __classPrivateFieldGet(this, _DIFHandler_handle, "f").resolve_pointer_address(addressWithOwnership);
530
+ const value = this.resolveDIFValueContainer(base[0]);
531
+ // init pointer
532
+ return this.initSharedValue(address, value, base[1], ownership, base[2]);
533
+ }
534
+ else {
535
+ // falltrough case, already in cache with correct ownership
444
536
  return cached;
445
537
  }
446
- // if not in cache, resolve from runtime
447
- const entry = __classPrivateFieldGet(this, _DIFHandler_handle, "f")
448
- .resolve_pointer_address_sync(address);
449
- const value = this.resolveDIFValueContainerSync(entry.value);
450
- this.initReference(address, value, entry.mut, entry.allowed_type);
451
- return value;
452
538
  }
453
539
  /**
454
540
  * Retrieves the original value from a proxy value if available
@@ -489,25 +575,28 @@ export class DIFHandler {
489
575
  return values?.map((value) => this.convertJSValueToDIFValueContainer(value)) ||
490
576
  null;
491
577
  }
492
- /**
493
- * Returns true if the given address is within the specified address range.
494
- */
495
- isPointerAddressInAdresses(address, range) {
496
- return range.has(address);
497
- }
498
578
  /**
499
579
  * Initializes a reference with the given value and mutability, by
500
580
  * adding a proxy wrapper if necessary, and setting up observation and caching on the JS side.
501
581
  */
502
- initReference(pointerAddress, value, mutability, allowedType = null) {
503
- let wrappedValue = this.wrapJSValue(value, pointerAddress, allowedType);
582
+ initSharedValue(pointerAddress, value, mutability, ownership, allowedType) {
583
+ let wrappedValue = this.wrapJSValue(value, pointerAddress, mutability, allowedType);
504
584
  let typeBinding = null;
505
585
  let metadata = undefined;
506
586
  // bind js value (if mutable, nominal type)
507
- const bindJSValue = mutability !== DIFSharedValueMutability.Immutable &&
508
- typeof allowedType == "string";
509
- if (bindJSValue && !(wrappedValue instanceof Ref)) {
510
- typeBinding = this.type_registry.getTypeBinding(allowedType);
587
+ const implType = typeof allowedType === "object" && allowedType !== null && "impl_type" in allowedType
588
+ ? allowedType.impl_type
589
+ : null;
590
+ if (implType && implType[0] === CoreLibTypeId.Map) {
591
+ // FIXME can we make this cleaner, or do we need it more generic?
592
+ allowedType = implType[0];
593
+ }
594
+ const bindJSValue = mutability !== SharedContainerMutability.Immutable &&
595
+ (typeof allowedType === "string" || typeof allowedType === "number");
596
+ if (bindJSValue && !(wrappedValue instanceof BaseSharedContainer)) {
597
+ typeBinding = typeof allowedType == "number"
598
+ ? this.type_registry.getTypeBindingByCoreLibTypeId(allowedType)
599
+ : this.type_registry.getTypeBinding(allowedType); // TS Bug
511
600
  if (typeBinding) {
512
601
  const { value, metadata: newMetadata } = typeBinding
513
602
  .bindValue(wrappedValue, pointerAddress);
@@ -517,12 +606,13 @@ export class DIFHandler {
517
606
  }
518
607
  // if not immutable, observe to keep the pointer 'live' and receive updates
519
608
  let observerId = null;
520
- if (mutability !== DIFSharedValueMutability.Immutable) {
521
- observerId = this.observePointerBindDirect(pointerAddress, (update) => {
609
+ if (mutability !== SharedContainerMutability.Immutable) {
610
+ observerId = this.observeSharedValueBindDirect(pointerAddress, (update) => {
611
+ const [sourceId, ...data] = update;
522
612
  // if source_id is not own transceiver id, handle pointer update
523
- if (update.source_id !== __classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f")) {
613
+ if (sourceId !== __classPrivateFieldGet(this, _DIFHandler_transceiver_id, "f")) {
524
614
  try {
525
- this.handlePointerUpdate(pointerAddress, wrappedValue, update.data, typeBinding);
615
+ this.handlePointerUpdate(pointerAddress, wrappedValue, data, typeBinding);
526
616
  }
527
617
  catch (e) {
528
618
  console.error("Error handling pointer update", e);
@@ -534,7 +624,7 @@ export class DIFHandler {
534
624
  if (observers) {
535
625
  for (const cb of observers.values()) {
536
626
  try {
537
- cb(update.data);
627
+ cb(data);
538
628
  }
539
629
  catch (e) {
540
630
  console.error("Error in pointer observer callback", e);
@@ -544,7 +634,7 @@ export class DIFHandler {
544
634
  console.debug("Pointer update received", update);
545
635
  });
546
636
  }
547
- this.cacheWrappedReferenceValue(pointerAddress, value, wrappedValue, observerId, metadata);
637
+ this.cacheWrappedReferenceValue(pointerAddress, ownership, value, wrappedValue, observerId, metadata);
548
638
  // set up observers
549
639
  return wrappedValue;
550
640
  }
@@ -555,8 +645,8 @@ export class DIFHandler {
555
645
  const deref = cached.value.deref();
556
646
  if (!deref)
557
647
  return false;
558
- if (deref instanceof Ref && update.kind === DIFUpdateKind.Replace) {
559
- deref.updateValueSilently(this.resolveDIFValueContainerSync(update.value));
648
+ if (deref instanceof BaseSharedContainer && update[0] === DIFUpdateKind.Replace) {
649
+ deref.updateValueSilently(this.resolveDIFValueContainer(update[1]));
560
650
  }
561
651
  // handle generic updates for values (depending on type interface definition)
562
652
  if (typeBinding) {
@@ -568,11 +658,12 @@ export class DIFHandler {
568
658
  * Caches the given reference value with the given address in the JS side cache.
569
659
  * The reference must already be wrapped if necessary.
570
660
  */
571
- cacheWrappedReferenceValue(address, originalValue, proxiedValue, observerId, metadata = {}) {
661
+ cacheWrappedReferenceValue(address, ownership, originalValue, proxiedValue, observerId, metadata = {}) {
572
662
  const isProxifiedValue = this.isWeakKey(originalValue) &&
573
663
  originalValue !== proxiedValue;
574
664
  __classPrivateFieldGet(this, _DIFHandler_cache, "f").set(address, {
575
665
  value: new WeakRef(proxiedValue),
666
+ maxOwnership: ownership,
576
667
  originalValue: isProxifiedValue ? originalValue : null,
577
668
  observerId,
578
669
  });
@@ -598,20 +689,33 @@ export class DIFHandler {
598
689
  __classPrivateFieldGet(this, _DIFHandler_observers, "f").delete(address);
599
690
  // if observer is active, unregister it
600
691
  if (observerId !== null) {
601
- this.unobserveReferenceBindDirect(address, observerId);
692
+ this.unobserveSharedValueBindDirect(address, observerId);
602
693
  }
603
694
  });
604
695
  finalizationRegistry.register(proxiedValue, address);
605
696
  }
606
- getCachedReference(address) {
697
+ getCachedStateForSharedContainer(address, ownership) {
698
+ if (!__classPrivateFieldGet(this, _DIFHandler_cache, "f").has(address)) {
699
+ return "not_cached";
700
+ }
607
701
  const cached = __classPrivateFieldGet(this, _DIFHandler_cache, "f").get(address);
608
- if (cached) {
609
- const deref = cached.value.deref();
610
- if (deref) {
611
- return deref;
612
- }
702
+ const deref = cached.value.deref();
703
+ if (!deref) {
704
+ throw new Error(`Cached reference for address ${address} is not dereferenceable`);
705
+ }
706
+ if (
707
+ // owership mismatch
708
+ (ownership === DIFSharedContainerOwnership.Owned &&
709
+ cached.maxOwnership !== DIFSharedContainerOwnership.Owned) || (cached.maxOwnership === DIFSharedContainerOwnership.Immutable &&
710
+ ownership === DIFSharedContainerOwnership.Mutable)) {
711
+ return "insufficient_ownership";
712
+ }
713
+ if (deref instanceof BaseSharedContainer) {
714
+ return deref.withOwnership(ownership);
715
+ }
716
+ else {
717
+ return deref;
613
718
  }
614
- return undefined;
615
719
  }
616
720
  /**
617
721
  * Creates a new reference containg the given JS value.
@@ -619,19 +723,24 @@ export class DIFHandler {
619
723
  * but also propagates changes between JS and the DATEX runtime.
620
724
  * If a reference for the given value already exists, an error is thrown.
621
725
  */
622
- createTransparentReference(value, allowedType = null, mutability = DIFSharedValueMutability.Mutable) {
623
- // if already bound to a reference, return the existing reference proxy (or the value itself)
726
+ createSharedValueFromJSValue(value, allowedType = null, mutability = SharedContainerMutability.Mutable) {
624
727
  const pointerAddress = this.getPointerAddressForValue(value);
625
728
  if (pointerAddress) {
626
729
  throw new Error(`Value is already bound to a reference ($${pointerAddress}). Cannot create a new reference for the same value.`);
627
730
  }
628
731
  const difValue = this.convertJSValueToDIFValueContainer(value);
629
- const ptrAddress = this.createSharedValueFromDIFValue(difValue, allowedType, mutability);
732
+ const ptrAddress = this.constructSharedValue(difValue, mutability, allowedType);
630
733
  // get inferred allowed type from pointer if not explicitly set
631
734
  if (!allowedType) {
632
- allowedType = __classPrivateFieldGet(this, _DIFHandler_handle, "f").resolve_pointer_address_sync(ptrAddress).allowed_type;
735
+ allowedType = __classPrivateFieldGet(this, _DIFHandler_handle, "f").resolve_pointer_address(ptrAddress)[2];
736
+ }
737
+ const base = this.initSharedValue(ptrAddress, value, mutability, DIFSharedContainerOwnership.Owned, allowedType);
738
+ if (base instanceof BaseSharedContainer) {
739
+ return new OwnedSharedContainer(base);
740
+ }
741
+ else {
742
+ return base;
633
743
  }
634
- return this.initReference(ptrAddress, value, mutability, allowedType);
635
744
  }
636
745
  isPrimitiveValue(value) {
637
746
  return value === null || value === undefined ||
@@ -647,17 +756,17 @@ export class DIFHandler {
647
756
  /**
648
757
  * Wraps a given JS value in a Ref proxy if necessary.
649
758
  */
650
- wrapJSValue(value, pointerAddress, _type = null) {
759
+ wrapJSValue(value, pointerAddress, mutability, _type = null) {
651
760
  // primitive values are always wrapped in a Ref proxy
652
761
  if (this.isWeakKey(value)) {
653
762
  return value;
654
763
  }
655
764
  else {
656
- return new Ref(value, pointerAddress, this);
765
+ return new BaseSharedContainer(value, pointerAddress, mutability, this);
657
766
  }
658
767
  }
659
- isRef(value) {
660
- return value instanceof Ref;
768
+ isBaseSharedContainer(value) {
769
+ return value instanceof BaseSharedContainer;
661
770
  }
662
771
  wrapJSObjectInProxy(value) {
663
772
  // deno-lint-ignore no-this-alias
@@ -665,14 +774,14 @@ export class DIFHandler {
665
774
  return new Proxy(value, {
666
775
  get(target, prop, receiver) {
667
776
  const val = Reflect.get(target, prop, receiver);
668
- if (val && typeof val === "object" && !self.isRef(val)) {
777
+ if (val && typeof val === "object" && !self.isBaseSharedContainer(val)) {
669
778
  return self.wrapJSObjectInProxy(val);
670
779
  }
671
780
  return val;
672
781
  },
673
782
  set(target, prop, newValue, receiver) {
674
783
  const oldValue = Reflect.get(target, prop, receiver);
675
- if (!self.isRef(oldValue)) {
784
+ if (!self.isBaseSharedContainer(oldValue)) {
676
785
  throw new Error(`Cannot modify non-Ref property "${String(prop)}"`);
677
786
  }
678
787
  oldValue.value = newValue;
@@ -712,92 +821,96 @@ export class DIFHandler {
712
821
  __classPrivateFieldGet(this, _DIFHandler_referenceMetadata, "f").get(__classPrivateFieldGet(this, _DIFHandler_proxyMapping, "f").get(value)?.deref()) ??
713
822
  null);
714
823
  }
715
- isReference(value) {
716
- return __classPrivateFieldGet(this, _DIFHandler_referenceMetadata, "f").has(value) ||
717
- __classPrivateFieldGet(this, _DIFHandler_proxyMapping, "f").has(value);
718
- }
719
- getReferenceProxy(value) {
720
- const reference = __classPrivateFieldGet(this, _DIFHandler_referenceMetadata, "f").get(value);
721
- if (reference) {
722
- return value;
723
- }
724
- const proxyRef = __classPrivateFieldGet(this, _DIFHandler_proxyMapping, "f").get(value);
725
- if (proxyRef) {
726
- const deref = proxyRef.deref();
727
- if (deref) {
728
- return deref;
729
- }
730
- else {
731
- panic("Reference proxy has been garbage collected");
732
- }
733
- }
734
- else {
735
- return null;
736
- }
737
- }
824
+ // FIXME do we need these two methods still?
825
+ // public isReference(value: object): boolean {
826
+ // return this.#referenceMetadata.has(value as CachedSharedContainer) ||
827
+ // this.#proxyMapping.has(value);
828
+ // }
829
+ // public getReferenceProxy<T>(value: CachedSharedContainer<T>): T | null {
830
+ // const reference = this.#referenceMetadata.get(value);
831
+ // if (reference) {
832
+ // return value;
833
+ // }
834
+ // const proxyRef = this.#proxyMapping.get(value);
835
+ // if (proxyRef) {
836
+ // const deref = proxyRef.deref();
837
+ // if (deref) {
838
+ // return deref as T;
839
+ // } else {
840
+ // panic("Reference proxy has been garbage collected");
841
+ // }
842
+ // } else {
843
+ // return null;
844
+ // }
845
+ // }
738
846
  /**
739
847
  * Converts a given JS value to its DIFValueContainer representation.
740
848
  * This method can be called statically or with an instance to use the instance's DIFHandler context.
741
849
  * NOTE: When called statically, there is no cache for already registered references, meaning that new references will be created
742
850
  * for the same object each time this method is called.
743
851
  */
744
- static convertJSValueToDIFValueContainer(value, difHandlerInstance) {
852
+ static convertJSValueToDIFValueContainer(value, difHandlerInstance, forceExplicitFormat = false) {
745
853
  // if the value is a registered reference, return its address
746
854
  const existingReference = difHandlerInstance &&
747
855
  difHandlerInstance.tryGetReferenceMetadata(value);
748
856
  if (existingReference) {
749
- return existingReference.address;
857
+ const ownership = __classPrivateFieldGet(difHandlerInstance, _DIFHandler_cache, "f").get(existingReference.address);
858
+ if (!ownership) {
859
+ throw new Error(`Reference metadata found for address ${existingReference.address} but no ownership info in cache`);
860
+ }
861
+ // move(x) -> function (x: OwnedValue) {}
862
+ return { $: combinePointerAddressWithOwnership(existingReference.address, ownership.maxOwnership) };
750
863
  }
751
- // assuming core values
752
864
  // TODO: handle custom types
753
865
  if (value === null) {
754
- return {
755
- value: null,
756
- };
866
+ return forceExplicitFormat ? [CoreLibTypeId.null, null] : null;
757
867
  }
758
868
  else if (value === undefined) {
759
- return {
760
- type: {
761
- kind: DIFTypeDefinitionKind.ImplType,
762
- def: [
763
- CoreTypeAddress.null,
764
- [JsLibTypeAddress.undefined],
765
- ],
766
- },
767
- value: null,
768
- };
869
+ return JS_UNDEFINED;
870
+ }
871
+ else if (typeof value === "string") {
872
+ return forceExplicitFormat ? [CoreLibTypeId.text, value] : value;
769
873
  }
770
874
  else if (typeof value === "boolean") {
771
- return {
772
- value,
773
- };
875
+ return forceExplicitFormat ? [CoreLibTypeId.boolean, value] : value;
774
876
  }
775
877
  else if (typeof value === "number") {
776
- return {
777
- value,
778
- };
878
+ return forceExplicitFormat ? [CoreLibTypeId.decimal_f64, value] : value;
779
879
  }
780
880
  else if (typeof value === "bigint") {
781
- return {
782
- type: CoreTypeAddress.integer_ibig,
783
- value: value.toString(), // convert bigint to string for DIFValue
784
- };
785
- }
786
- else if (typeof value === "string") {
787
- return {
788
- value,
789
- };
881
+ return ibig(value);
790
882
  }
791
883
  else if (value instanceof Endpoint) {
792
- return {
793
- type: CoreTypeAddress.endpoint,
794
- value: value.toString(),
795
- };
884
+ return [CoreLibTypeId.endpoint, value.toString()];
885
+ }
886
+ else if (value instanceof Tagged) {
887
+ // special case: empty tagged value
888
+ if (value.value === EMPTY_TAG) {
889
+ return [CoreLibTypeId.null, null, {
890
+ tagged_type: [value.tag, CoreLibTypeId.Unit],
891
+ }];
892
+ }
893
+ const inner = this.convertJSValueToDIFValueContainer(value.value, difHandlerInstance, true);
894
+ if (inner instanceof Array) {
895
+ return [inner[0], inner[1], {
896
+ tagged_type: [value.tag, inner[2] || inner[0]], // TODO: nullable type
897
+ }];
898
+ }
899
+ else if (typeof inner === "object" && inner !== null) {
900
+ unimplemented("Support nested shared reference value in tagged value");
901
+ }
902
+ else {
903
+ unreachable("convertJSValueToDIFValueContainer with forceExplicitFormat should return an array or object");
904
+ }
905
+ }
906
+ else if (value instanceof Range) {
907
+ return [CoreLibTypeId.Range, [
908
+ this.convertJSValueToDIFValueContainer(value.start),
909
+ this.convertJSValueToDIFValueContainer(value.end),
910
+ ]];
796
911
  }
797
912
  else if (Array.isArray(value)) {
798
- return {
799
- value: value.map((v) => this.convertJSValueToDIFValueContainer(v)),
800
- };
913
+ return [CoreLibTypeId.List, value.map((v) => this.convertJSValueToDIFValueContainer(v))];
801
914
  }
802
915
  else if (value instanceof Map) {
803
916
  const map = value
@@ -805,19 +918,16 @@ export class DIFHandler {
805
918
  this.convertJSValueToDIFValueContainer(k),
806
919
  this.convertJSValueToDIFValueContainer(v),
807
920
  ]).toArray();
808
- return {
809
- type: CoreTypeAddress.map,
810
- value: map,
811
- };
921
+ return [CoreLibTypeId.Map, map, {
922
+ impl_type: [CoreLibTypeId.Map, [JsLibTypeAddress.map]],
923
+ }];
812
924
  }
813
925
  else if (typeof value === "object") {
814
926
  const map = {};
815
927
  for (const [key, val] of Object.entries(value)) {
816
928
  map[key] = this.convertJSValueToDIFValueContainer(val);
817
929
  }
818
- return {
819
- value: map,
820
- };
930
+ return [CoreLibTypeId.Map, map];
821
931
  }
822
932
  throw new Error("Unsupported type for conversion to DIFValue");
823
933
  }
@@ -836,13 +946,7 @@ export class DIFHandler {
836
946
  triggerSet(pointerAddress, key, value) {
837
947
  const difKey = this.convertJSValueToDIFValueContainer(key);
838
948
  const difValue = this.convertJSValueToDIFValueContainer(value);
839
- const update = {
840
- kind: DIFUpdateKind.Set,
841
- key: { kind: "value", value: difKey },
842
- value: difValue,
843
- };
844
- console.log("Triggering set update", update);
845
- this.updateReference(pointerAddress, update);
949
+ this.updateSharedValue(pointerAddress, setEntry(createDIFProperty(difKey, DIFPropertyKind.ValueContainer), difValue));
846
950
  }
847
951
  /**
848
952
  * Triggers a 'set' update for the given pointer address, index and value.
@@ -852,73 +956,41 @@ export class DIFHandler {
852
956
  throw new Error("Index must be a non-negative integer");
853
957
  }
854
958
  const difValue = this.convertJSValueToDIFValueContainer(value);
855
- const update = {
856
- kind: DIFUpdateKind.Set,
857
- key: { kind: "index", value: Number(index) },
858
- value: difValue,
859
- };
860
- console.log("Triggering index set update", update);
861
- this.updateReference(pointerAddress, update);
959
+ this.updateSharedValue(pointerAddress, setEntry(createDIFProperty(Number(index), DIFPropertyKind.Index), difValue));
862
960
  }
863
961
  /**
864
962
  * Triggers an 'append' update for the given pointer address and value.
865
963
  */
866
964
  triggerAppend(pointerAddress, value) {
867
965
  const difValue = this.convertJSValueToDIFValueContainer(value);
868
- const update = {
869
- kind: DIFUpdateKind.Append,
870
- value: difValue,
871
- };
872
- console.log("Triggering append update", update);
873
- this.updateReference(pointerAddress, update);
966
+ this.updateSharedValue(pointerAddress, appendEntry(difValue));
874
967
  }
875
968
  /**
876
969
  * Triggers a 'replace' update for the given pointer address and key.
877
970
  */
878
971
  triggerReplace(pointerAddress, value) {
879
972
  const difValue = this.convertJSValueToDIFValueContainer(value);
880
- const update = {
881
- kind: DIFUpdateKind.Replace,
882
- value: difValue,
883
- };
884
- console.log("Triggering replace update", update);
885
- this.updateReference(pointerAddress, update);
973
+ this.updateSharedValue(pointerAddress, replace(difValue));
886
974
  }
887
975
  /**
888
976
  * Triggers a 'delete' update for the given pointer address and key.
889
977
  */
890
978
  triggerDelete(pointerAddress, key) {
891
979
  const difKey = this.convertJSValueToDIFValueContainer(key);
892
- const update = {
893
- kind: DIFUpdateKind.Delete,
894
- key: { kind: "value", value: difKey },
895
- };
896
- console.log("Triggering delete update", update);
897
- this.updateReference(pointerAddress, update);
980
+ this.updateSharedValue(pointerAddress, deleteEntry(createDIFProperty(difKey, DIFPropertyKind.ValueContainer)));
898
981
  }
899
982
  /**
900
983
  * Triggers a 'clear' update for the given pointer address.
901
984
  */
902
985
  triggerClear(pointerAddress) {
903
- const update = {
904
- kind: DIFUpdateKind.Clear,
905
- };
906
- console.log("Triggering clear update", update);
907
- this.updateReference(pointerAddress, update);
986
+ this.updateSharedValue(pointerAddress, clear());
908
987
  }
909
988
  /**
910
989
  * Triggers a 'list splice' update for the given pointer address.
911
990
  */
912
991
  triggerListSplice(pointerAddress, start, deleteCount, items) {
913
992
  const difItems = items.map((item) => this.convertJSValueToDIFValueContainer(item));
914
- const update = {
915
- kind: DIFUpdateKind.ListSplice,
916
- start,
917
- delete_count: deleteCount,
918
- items: difItems,
919
- };
920
- console.log("Triggering list splice update", update);
921
- this.updateReference(pointerAddress, update);
993
+ this.updateSharedValue(pointerAddress, listSplice(start, deleteCount, difItems));
922
994
  }
923
995
  }
924
996
  _DIFHandler_runtime = new WeakMap(), _DIFHandler_handle = new WeakMap(), _DIFHandler_transceiver_id = new WeakMap(), _DIFHandler_cache = new WeakMap(), _DIFHandler_proxyMapping = new WeakMap(), _DIFHandler_referenceMetadata = new WeakMap(), _DIFHandler_observers = new WeakMap(), _DIFHandler_type_registry = new WeakMap();