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