@ricsam/quickjs-core 0.2.13 → 0.2.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.
package/dist/cjs/url.cjs CHANGED
@@ -31,26 +31,36 @@ var __export = (target, all) => {
31
31
  var exports_url = {};
32
32
  __export(exports_url, {
33
33
  createURLClass: () => createURLClass,
34
+ addURLSearchParamsLinkage: () => addURLSearchParamsLinkage,
34
35
  addURLSearchParamsGetter: () => addURLSearchParamsGetter
35
36
  });
36
37
  module.exports = __toCommonJS(exports_url);
37
38
  var import_class_builder = require("./class-builder.cjs");
39
+ function rebuildURLHref(state) {
40
+ let userinfo = "";
41
+ if (state.username) {
42
+ userinfo = state.password ? `${state.username}:${state.password}@` : `${state.username}@`;
43
+ }
44
+ state.href = `${state.protocol}//${userinfo}${state.host}${state.pathname}${state.search}${state.hash}`;
45
+ state.origin = `${state.protocol}//${state.host}`;
46
+ }
38
47
  function createURLClass(context, stateMap) {
39
48
  return import_class_builder.defineClass(context, stateMap, {
40
49
  name: "URL",
41
50
  construct: (args) => {
42
- const urlString = args[0];
51
+ const urlInput = args[0];
43
52
  const base = args[1];
44
- if (urlString === undefined) {
53
+ if (urlInput === undefined) {
45
54
  throw new TypeError("Failed to construct 'URL': 1 argument required, but only 0 present.");
46
55
  }
56
+ const urlString = typeof urlInput === "object" && urlInput !== null && "href" in urlInput ? urlInput.href : String(urlInput);
47
57
  let parsed;
48
58
  try {
49
59
  if (base !== undefined) {
50
60
  const baseStr = typeof base === "object" && base !== null && "href" in base ? base.href : String(base);
51
- parsed = new globalThis.URL(String(urlString), baseStr);
61
+ parsed = new globalThis.URL(urlString, baseStr);
52
62
  } else {
53
- parsed = new globalThis.URL(String(urlString));
63
+ parsed = new globalThis.URL(urlString);
54
64
  }
55
65
  } catch (e) {
56
66
  throw new TypeError(`Failed to construct 'URL': Invalid URL`);
@@ -73,21 +83,56 @@ function createURLClass(context, stateMap) {
73
83
  hash: {
74
84
  get() {
75
85
  return this.hash;
86
+ },
87
+ set(value) {
88
+ this.hash = value.startsWith("#") ? value : `#${value}`;
89
+ rebuildURLHref(this);
76
90
  }
77
91
  },
78
92
  host: {
79
93
  get() {
80
94
  return this.host;
95
+ },
96
+ set(value) {
97
+ const colonIndex = value.lastIndexOf(":");
98
+ if (colonIndex > -1 && !value.includes("]", colonIndex)) {
99
+ this.hostname = value.slice(0, colonIndex);
100
+ this.port = value.slice(colonIndex + 1);
101
+ } else {
102
+ this.hostname = value;
103
+ this.port = "";
104
+ }
105
+ this.host = value;
106
+ rebuildURLHref(this);
81
107
  }
82
108
  },
83
109
  hostname: {
84
110
  get() {
85
111
  return this.hostname;
112
+ },
113
+ set(value) {
114
+ this.hostname = value;
115
+ this.host = this.port ? `${value}:${this.port}` : value;
116
+ rebuildURLHref(this);
86
117
  }
87
118
  },
88
119
  href: {
89
120
  get() {
90
121
  return this.href;
122
+ },
123
+ set(value) {
124
+ const parsed = new globalThis.URL(value);
125
+ this.hash = parsed.hash;
126
+ this.host = parsed.host;
127
+ this.hostname = parsed.hostname;
128
+ this.href = parsed.href;
129
+ this.origin = parsed.origin;
130
+ this.password = parsed.password;
131
+ this.pathname = parsed.pathname;
132
+ this.port = parsed.port;
133
+ this.protocol = parsed.protocol;
134
+ this.search = parsed.search;
135
+ this.username = parsed.username;
91
136
  }
92
137
  },
93
138
  origin: {
@@ -98,31 +143,57 @@ function createURLClass(context, stateMap) {
98
143
  password: {
99
144
  get() {
100
145
  return this.password;
146
+ },
147
+ set(value) {
148
+ this.password = value;
149
+ rebuildURLHref(this);
101
150
  }
102
151
  },
103
152
  pathname: {
104
153
  get() {
105
154
  return this.pathname;
155
+ },
156
+ set(value) {
157
+ this.pathname = value.startsWith("/") ? value : `/${value}`;
158
+ rebuildURLHref(this);
106
159
  }
107
160
  },
108
161
  port: {
109
162
  get() {
110
163
  return this.port;
164
+ },
165
+ set(value) {
166
+ this.port = value;
167
+ this.host = value ? `${this.hostname}:${value}` : this.hostname;
168
+ rebuildURLHref(this);
111
169
  }
112
170
  },
113
171
  protocol: {
114
172
  get() {
115
173
  return this.protocol;
174
+ },
175
+ set(value) {
176
+ this.protocol = value.endsWith(":") ? value : `${value}:`;
177
+ this.origin = `${this.protocol}//${this.host}`;
178
+ rebuildURLHref(this);
116
179
  }
117
180
  },
118
181
  search: {
119
182
  get() {
120
183
  return this.search;
184
+ },
185
+ set(value) {
186
+ this.search = value && !value.startsWith("?") ? `?${value}` : value;
187
+ rebuildURLHref(this);
121
188
  }
122
189
  },
123
190
  username: {
124
191
  get() {
125
192
  return this.username;
193
+ },
194
+ set(value) {
195
+ this.username = value;
196
+ rebuildURLHref(this);
126
197
  }
127
198
  }
128
199
  },
@@ -132,9 +203,6 @@ function createURLClass(context, stateMap) {
132
203
  },
133
204
  toJSON() {
134
205
  return this.href;
135
- },
136
- __getSearch__() {
137
- return this.search;
138
206
  }
139
207
  },
140
208
  staticMethods: {
@@ -153,18 +221,42 @@ function createURLClass(context, stateMap) {
153
221
  }
154
222
  });
155
223
  }
156
- function addURLSearchParamsGetter(context) {
224
+ function addURLSearchParamsLinkage(context) {
157
225
  const result = context.evalCode(`
158
226
  (function() {
159
- const searchParamsCache = new Map();
160
-
161
227
  Object.defineProperty(URL.prototype, 'searchParams', {
162
228
  get: function() {
163
- const instanceId = this.__instanceId__;
164
- if (!searchParamsCache.has(instanceId)) {
165
- searchParamsCache.set(instanceId, new URLSearchParams(this.__getSearch__()));
229
+ // Cache the URLSearchParams instance on first access
230
+ if (!this._cachedSearchParams) {
231
+ const url = this;
232
+ const params = new URLSearchParams(this.search);
233
+
234
+ // Wrap mutating methods to sync back to URL
235
+ const originalSet = params.set.bind(params);
236
+ const originalAppend = params.append.bind(params);
237
+ const originalDelete = params.delete.bind(params);
238
+ const originalSort = params.sort.bind(params);
239
+
240
+ params.set = function(name, value) {
241
+ originalSet(name, value);
242
+ url.search = this.toString();
243
+ };
244
+ params.append = function(name, value) {
245
+ originalAppend(name, value);
246
+ url.search = this.toString();
247
+ };
248
+ params.delete = function(name, value) {
249
+ originalDelete(name, value);
250
+ url.search = this.toString();
251
+ };
252
+ params.sort = function() {
253
+ originalSort();
254
+ url.search = this.toString();
255
+ };
256
+
257
+ this._cachedSearchParams = params;
166
258
  }
167
- return searchParamsCache.get(instanceId);
259
+ return this._cachedSearchParams;
168
260
  },
169
261
  enumerable: true,
170
262
  configurable: true
@@ -174,10 +266,11 @@ function addURLSearchParamsGetter(context) {
174
266
  if (result.error) {
175
267
  const err = context.dump(result.error);
176
268
  result.error.dispose();
177
- throw new Error(`Failed to add searchParams getter: ${JSON.stringify(err)}`);
269
+ throw new Error(`Failed to setup URL/URLSearchParams linkage: ${JSON.stringify(err)}`);
178
270
  }
179
271
  result.value.dispose();
180
272
  }
273
+ var addURLSearchParamsGetter = addURLSearchParamsLinkage;
181
274
  })
182
275
 
183
- //# debugId=C3940F5C588B349864756E2164756E21
276
+ //# debugId=5358D58086DA4A4164756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/url.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"./types.cjs\";\nimport { defineClass } from \"./class-builder.cjs\";\n\n/**\n * Internal state for URL\n */\nexport interface URLState {\n hash: string;\n host: string;\n hostname: string;\n href: string;\n origin: string;\n password: string;\n pathname: string;\n port: string;\n protocol: string;\n search: string;\n username: string;\n}\n\n/**\n * Create the URL class for QuickJS\n *\n * Note: The searchParams property is added separately via evalCode\n * after this class is registered, as it needs to return a URLSearchParams instance.\n */\nexport function createURLClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<URLState>(context, stateMap, {\n name: \"URL\",\n construct: (args) => {\n const urlString = args[0];\n const base = args[1];\n\n if (urlString === undefined) {\n throw new TypeError(\"Failed to construct 'URL': 1 argument required, but only 0 present.\");\n }\n\n let parsed: globalThis.URL;\n try {\n if (base !== undefined) {\n // Handle base URL\n const baseStr = typeof base === \"object\" && base !== null && \"href\" in base\n ? (base as URLState).href\n : String(base);\n parsed = new globalThis.URL(String(urlString), baseStr);\n } else {\n parsed = new globalThis.URL(String(urlString));\n }\n } catch (e) {\n throw new TypeError(`Failed to construct 'URL': Invalid URL`);\n }\n\n return {\n hash: parsed.hash,\n host: parsed.host,\n hostname: parsed.hostname,\n href: parsed.href,\n origin: parsed.origin,\n password: parsed.password,\n pathname: parsed.pathname,\n port: parsed.port,\n protocol: parsed.protocol,\n search: parsed.search,\n username: parsed.username,\n };\n },\n properties: {\n hash: {\n get(this: URLState) {\n return this.hash;\n },\n },\n host: {\n get(this: URLState) {\n return this.host;\n },\n },\n hostname: {\n get(this: URLState) {\n return this.hostname;\n },\n },\n href: {\n get(this: URLState) {\n return this.href;\n },\n },\n origin: {\n get(this: URLState) {\n return this.origin;\n },\n },\n password: {\n get(this: URLState) {\n return this.password;\n },\n },\n pathname: {\n get(this: URLState) {\n return this.pathname;\n },\n },\n port: {\n get(this: URLState) {\n return this.port;\n },\n },\n protocol: {\n get(this: URLState) {\n return this.protocol;\n },\n },\n search: {\n get(this: URLState) {\n return this.search;\n },\n },\n username: {\n get(this: URLState) {\n return this.username;\n },\n },\n },\n methods: {\n toString(this: URLState): string {\n return this.href;\n },\n toJSON(this: URLState): string {\n return this.href;\n },\n // Private method to get search for URLSearchParams creation\n __getSearch__(this: URLState): string {\n return this.search;\n },\n },\n staticMethods: {\n canParse(url: unknown, base?: unknown): boolean {\n try {\n if (base !== undefined) {\n new globalThis.URL(String(url), String(base));\n } else {\n new globalThis.URL(String(url));\n }\n return true;\n } catch {\n return false;\n }\n },\n },\n });\n}\n\n/**\n * Add searchParams getter to URL prototype using evalCode\n * This must be called after both URL and URLSearchParams are registered as globals\n */\nexport function addURLSearchParamsGetter(context: QuickJSContext): void {\n // Use a WeakMap-like pattern with a Map keyed by instance ID\n // Each URL instance will cache its URLSearchParams\n const result = context.evalCode(`\n (function() {\n const searchParamsCache = new Map();\n\n Object.defineProperty(URL.prototype, 'searchParams', {\n get: function() {\n const instanceId = this.__instanceId__;\n if (!searchParamsCache.has(instanceId)) {\n searchParamsCache.set(instanceId, new URLSearchParams(this.__getSearch__()));\n }\n return searchParamsCache.get(instanceId);\n },\n enumerable: true,\n configurable: true\n });\n })();\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to add searchParams getter: ${JSON.stringify(err)}`);\n }\n result.value.dispose();\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { StateMap } from \"./types.cjs\";\nimport { defineClass } from \"./class-builder.cjs\";\n\n/**\n * Internal state for URL\n */\nexport interface URLState {\n hash: string;\n host: string;\n hostname: string;\n href: string;\n origin: string;\n password: string;\n pathname: string;\n port: string;\n protocol: string;\n search: string;\n username: string;\n}\n\n/**\n * Helper to rebuild the href from URL components\n */\nfunction rebuildURLHref(state: URLState): void {\n // Build userinfo part\n let userinfo = \"\";\n if (state.username) {\n userinfo = state.password\n ? `${state.username}:${state.password}@`\n : `${state.username}@`;\n }\n\n // Build the href\n state.href = `${state.protocol}//${userinfo}${state.host}${state.pathname}${state.search}${state.hash}`;\n\n // Update origin\n state.origin = `${state.protocol}//${state.host}`;\n}\n\n/**\n * Create the URL class for QuickJS\n *\n * Note: The searchParams property is added separately via evalCode\n * after this class is registered, as it needs to return a URLSearchParams instance.\n */\nexport function createURLClass(\n context: QuickJSContext,\n stateMap: StateMap\n): QuickJSHandle {\n return defineClass<URLState>(context, stateMap, {\n name: \"URL\",\n construct: (args) => {\n const urlInput = args[0];\n const base = args[1];\n\n if (urlInput === undefined) {\n throw new TypeError(\"Failed to construct 'URL': 1 argument required, but only 0 present.\");\n }\n\n // Handle URL object as first argument (extract href)\n const urlString = typeof urlInput === \"object\" && urlInput !== null && \"href\" in urlInput\n ? (urlInput as URLState).href\n : String(urlInput);\n\n let parsed: globalThis.URL;\n try {\n if (base !== undefined) {\n // Handle base URL\n const baseStr = typeof base === \"object\" && base !== null && \"href\" in base\n ? (base as URLState).href\n : String(base);\n parsed = new globalThis.URL(urlString, baseStr);\n } else {\n parsed = new globalThis.URL(urlString);\n }\n } catch (e) {\n throw new TypeError(`Failed to construct 'URL': Invalid URL`);\n }\n\n return {\n hash: parsed.hash,\n host: parsed.host,\n hostname: parsed.hostname,\n href: parsed.href,\n origin: parsed.origin,\n password: parsed.password,\n pathname: parsed.pathname,\n port: parsed.port,\n protocol: parsed.protocol,\n search: parsed.search,\n username: parsed.username,\n };\n },\n properties: {\n hash: {\n get(this: URLState) {\n return this.hash;\n },\n set(this: URLState, value: string) {\n this.hash = value.startsWith(\"#\") ? value : `#${value}`;\n rebuildURLHref(this);\n },\n },\n host: {\n get(this: URLState) {\n return this.host;\n },\n set(this: URLState, value: string) {\n // Parse host into hostname and port\n const colonIndex = value.lastIndexOf(\":\");\n if (colonIndex > -1 && !value.includes(\"]\", colonIndex)) {\n this.hostname = value.slice(0, colonIndex);\n this.port = value.slice(colonIndex + 1);\n } else {\n this.hostname = value;\n this.port = \"\";\n }\n this.host = value;\n rebuildURLHref(this);\n },\n },\n hostname: {\n get(this: URLState) {\n return this.hostname;\n },\n set(this: URLState, value: string) {\n this.hostname = value;\n this.host = this.port ? `${value}:${this.port}` : value;\n rebuildURLHref(this);\n },\n },\n href: {\n get(this: URLState) {\n return this.href;\n },\n set(this: URLState, value: string) {\n // Parse the new href and update all properties\n const parsed = new globalThis.URL(value);\n this.hash = parsed.hash;\n this.host = parsed.host;\n this.hostname = parsed.hostname;\n this.href = parsed.href;\n this.origin = parsed.origin;\n this.password = parsed.password;\n this.pathname = parsed.pathname;\n this.port = parsed.port;\n this.protocol = parsed.protocol;\n this.search = parsed.search;\n this.username = parsed.username;\n },\n },\n origin: {\n get(this: URLState) {\n return this.origin;\n },\n // origin is read-only per spec\n },\n password: {\n get(this: URLState) {\n return this.password;\n },\n set(this: URLState, value: string) {\n this.password = value;\n rebuildURLHref(this);\n },\n },\n pathname: {\n get(this: URLState) {\n return this.pathname;\n },\n set(this: URLState, value: string) {\n this.pathname = value.startsWith(\"/\") ? value : `/${value}`;\n rebuildURLHref(this);\n },\n },\n port: {\n get(this: URLState) {\n return this.port;\n },\n set(this: URLState, value: string) {\n this.port = value;\n this.host = value ? `${this.hostname}:${value}` : this.hostname;\n rebuildURLHref(this);\n },\n },\n protocol: {\n get(this: URLState) {\n return this.protocol;\n },\n set(this: URLState, value: string) {\n this.protocol = value.endsWith(\":\") ? value : `${value}:`;\n // Update origin\n this.origin = `${this.protocol}//${this.host}`;\n rebuildURLHref(this);\n },\n },\n search: {\n get(this: URLState) {\n return this.search;\n },\n set(this: URLState, value: string) {\n this.search = value && !value.startsWith(\"?\") ? `?${value}` : value;\n rebuildURLHref(this);\n },\n },\n username: {\n get(this: URLState) {\n return this.username;\n },\n set(this: URLState, value: string) {\n this.username = value;\n rebuildURLHref(this);\n },\n },\n },\n methods: {\n toString(this: URLState): string {\n return this.href;\n },\n toJSON(this: URLState): string {\n return this.href;\n },\n },\n staticMethods: {\n canParse(url: unknown, base?: unknown): boolean {\n try {\n if (base !== undefined) {\n new globalThis.URL(String(url), String(base));\n } else {\n new globalThis.URL(String(url));\n }\n return true;\n } catch {\n return false;\n }\n },\n },\n });\n}\n\n/**\n * Add searchParams getter to URL prototype using evalCode\n * This must be called after both URL and URLSearchParams are registered as globals\n *\n * The getter creates a URLSearchParams instance on first access and wraps its\n * mutating methods (set, append, delete, sort) to sync changes back to the URL.\n * This eliminates cross-module coupling by keeping all sync logic in JavaScript.\n */\nexport function addURLSearchParamsLinkage(context: QuickJSContext): void {\n const result = context.evalCode(`\n (function() {\n Object.defineProperty(URL.prototype, 'searchParams', {\n get: function() {\n // Cache the URLSearchParams instance on first access\n if (!this._cachedSearchParams) {\n const url = this;\n const params = new URLSearchParams(this.search);\n\n // Wrap mutating methods to sync back to URL\n const originalSet = params.set.bind(params);\n const originalAppend = params.append.bind(params);\n const originalDelete = params.delete.bind(params);\n const originalSort = params.sort.bind(params);\n\n params.set = function(name, value) {\n originalSet(name, value);\n url.search = this.toString();\n };\n params.append = function(name, value) {\n originalAppend(name, value);\n url.search = this.toString();\n };\n params.delete = function(name, value) {\n originalDelete(name, value);\n url.search = this.toString();\n };\n params.sort = function() {\n originalSort();\n url.search = this.toString();\n };\n\n this._cachedSearchParams = params;\n }\n return this._cachedSearchParams;\n },\n enumerable: true,\n configurable: true\n });\n })();\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to setup URL/URLSearchParams linkage: ${JSON.stringify(err)}`);\n }\n result.value.dispose();\n}\n\n/**\n * @deprecated Use addURLSearchParamsLinkage instead\n */\nexport const addURLSearchParamsGetter = addURLSearchParamsLinkage;\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "C3940F5C588B349864756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "5358D58086DA4A4164756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -10,6 +10,25 @@ import {
10
10
  cleanupInstanceState as cleanupState,
11
11
  clearAllInstanceState as clearAllState
12
12
  } from "./instance-state.mjs";
13
+ var ERROR_TYPES = ["TypeError", "RangeError", "SyntaxError", "ReferenceError", "URIError", "EvalError"];
14
+ function createTypedError(context, error) {
15
+ if (ERROR_TYPES.includes(error.name)) {
16
+ const ctor = context.getProp(context.global, error.name);
17
+ if (context.typeof(ctor) === "function") {
18
+ const messageHandle = context.newString(error.message);
19
+ const result = context.callFunction(ctor, context.undefined, messageHandle);
20
+ messageHandle.dispose();
21
+ ctor.dispose();
22
+ if (!result.error) {
23
+ return result.value;
24
+ }
25
+ result.error.dispose();
26
+ } else {
27
+ ctor.dispose();
28
+ }
29
+ }
30
+ return context.newError(error.message);
31
+ }
13
32
  function createStateMap() {
14
33
  return new WeakMap;
15
34
  }
@@ -85,7 +104,10 @@ function defineClass(context, stateMap, definition) {
85
104
  }
86
105
  return marshal(context, result2);
87
106
  } catch (error) {
88
- throw context.newError(error instanceof Error ? error.message : String(error));
107
+ if (error instanceof Error) {
108
+ throw createTypedError(context, error);
109
+ }
110
+ throw context.newError(String(error));
89
111
  }
90
112
  });
91
113
  context.setProp(context.global, "__hostCall__", hostCallFn);
@@ -108,7 +130,20 @@ function defineClass(context, stateMap, definition) {
108
130
  staticMethods: definition.staticMethods
109
131
  };
110
132
  classCallbackRegistry.set(className, callbacks);
111
- let classCode = `(function() {
133
+ const hasParent = definition.extends !== undefined;
134
+ if (hasParent) {
135
+ context.setProp(context.global, "__tempParentClass__", definition.extends);
136
+ }
137
+ let classCode = hasParent ? `(function() {
138
+ const __className__ = ${JSON.stringify(className)};
139
+ const __ParentClass__ = __tempParentClass__;
140
+
141
+ class ${className} extends __ParentClass__ {
142
+ constructor(...args) {
143
+ super();
144
+ // __instanceId__ is already set by parent class, just call our construct
145
+ __hostCall__(__className__, "__construct__", this.__instanceId__, ...args);
146
+ }` : `(function() {
112
147
  const __className__ = ${JSON.stringify(className)};
113
148
 
114
149
  class ${className} {
@@ -120,8 +155,7 @@ function defineClass(context, stateMap, definition) {
120
155
  configurable: false
121
156
  });
122
157
  __hostCall__(__className__, "__construct__", this.__instanceId__, ...args);
123
- }
124
- `;
158
+ }`;
125
159
  if (definition.methods) {
126
160
  for (const methodName of Object.keys(definition.methods)) {
127
161
  classCode += `
@@ -171,6 +205,9 @@ function defineClass(context, stateMap, definition) {
171
205
  return ${className};
172
206
  })()`;
173
207
  const result = context.evalCode(classCode);
208
+ if (hasParent) {
209
+ context.setProp(context.global, "__tempParentClass__", context.undefined);
210
+ }
174
211
  if (result.error) {
175
212
  const error = context.dump(result.error);
176
213
  result.error.dispose();
@@ -221,4 +258,4 @@ export {
221
258
  cleanupInstanceState
222
259
  };
223
260
 
224
- //# debugId=B233FA1A9250E66764756E2164756E21
261
+ //# debugId=1C141B77B235492264756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/class-builder.ts"],
4
4
  "sourcesContent": [
5
- "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { ClassDefinition, StateMap } from \"./types.mjs\";\nimport { unmarshal } from \"./unmarshal.mjs\";\nimport { marshal } from \"./marshal.mjs\";\nimport {\n nextInstanceId,\n registerInstance,\n getInstanceStateById as getStateById,\n setInstanceStateById,\n cleanupInstanceState as cleanupState,\n clearAllInstanceState as clearAllState,\n} from \"./instance-state.mjs\";\n\n/**\n * Create a new StateMap for tracking object internal states\n */\nexport function createStateMap(): StateMap {\n return new WeakMap();\n}\n\n/**\n * Get the internal state associated with a QuickJS object handle\n */\nexport function getState<T extends object>(\n stateMap: StateMap,\n handle: QuickJSHandle\n): T | undefined {\n return stateMap.get(handle) as T | undefined;\n}\n\n/**\n * Set the internal state associated with a QuickJS object handle\n */\nexport function setState<T extends object>(\n stateMap: StateMap,\n handle: QuickJSHandle,\n state: T\n): void {\n stateMap.set(handle, state);\n}\n\n// Instance state is now managed by instance-state.ts\n\n/**\n * Define a class in the QuickJS context\n *\n * Uses evalCode to create a proper JavaScript class that can be called with 'new'.\n * Host-side callbacks are registered and invoked by the JavaScript class.\n *\n * @returns Handle to the class constructor (caller must manage disposal)\n *\n * @example\n * const Point = defineClass(context, stateMap, {\n * name: \"Point\",\n * construct: ([x, y]) => ({ x: Number(x), y: Number(y) }),\n * methods: {\n * distance(this: { x: number; y: number }) {\n * return Math.sqrt(this.x ** 2 + this.y ** 2);\n * }\n * },\n * properties: {\n * x: {\n * get(this: { x: number }) { return this.x; },\n * set(this: { x: number }, v: unknown) { this.x = Number(v); }\n * }\n * }\n * });\n * context.setProp(context.global, \"Point\", Point);\n */\nexport function defineClass<TState extends object>(\n context: QuickJSContext,\n stateMap: StateMap,\n definition: ClassDefinition<TState>\n): QuickJSHandle {\n const className = definition.name;\n\n // Create the __hostCall__ function if it doesn't exist\n const existingHostCall = context.getProp(context.global, \"__hostCall__\");\n const hasHostCall = context.typeof(existingHostCall) === \"function\";\n existingHostCall.dispose();\n\n if (!hasHostCall) {\n const hostCallFn = context.newFunction(\"__hostCall__\", (classNameHandle, actionHandle, instanceIdHandle, ...argHandles) => {\n const classNameStr = context.getString(classNameHandle);\n const action = context.getString(actionHandle);\n const instanceId = context.getNumber(instanceIdHandle);\n const args = argHandles.map((h) => unmarshal(context, h));\n\n const callbacks = classCallbackRegistry.get(classNameStr);\n if (!callbacks) {\n throw context.newError(`No callbacks registered for class ${classNameStr}`);\n }\n\n const state = getStateById<TState>(instanceId);\n\n try {\n let result: unknown;\n\n if (action === \"__construct__\") {\n // Constructor call\n if (callbacks.construct) {\n const newState = callbacks.construct(args);\n // Register instance with className for cross-class access\n registerInstance(instanceId, classNameStr, newState);\n result = undefined;\n }\n } else if (action.startsWith(\"get:\")) {\n // Getter call\n const propName = action.slice(4);\n const getter = callbacks.properties?.[propName]?.get;\n if (getter && state) {\n result = getter.call(state);\n }\n } else if (action.startsWith(\"set:\")) {\n // Setter call\n const propName = action.slice(4);\n const setter = callbacks.properties?.[propName]?.set;\n if (setter && state) {\n setter.call(state, args[0]);\n }\n result = undefined;\n } else if (action.startsWith(\"static:\")) {\n // Static method call\n const methodName = action.slice(7);\n const staticMethod = callbacks.staticMethods?.[methodName];\n if (staticMethod) {\n result = staticMethod(...args);\n }\n } else {\n // Instance method call\n const method = callbacks.methods?.[action];\n if (method && state) {\n result = method.call(state, ...args);\n }\n }\n\n // Handle promises\n if (result instanceof Promise) {\n const deferred = context.newPromise();\n result\n .then((resolved) => {\n const resolvedHandle = marshal(context, resolved);\n deferred.resolve(resolvedHandle);\n resolvedHandle.dispose();\n context.runtime.executePendingJobs();\n })\n .catch((error) => {\n const errorHandle = marshal(\n context,\n error instanceof Error\n ? { name: error.name, message: error.message }\n : { message: String(error) }\n );\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n });\n return deferred.handle;\n }\n\n return marshal(context, result);\n } catch (error) {\n throw context.newError(\n error instanceof Error ? error.message : String(error)\n );\n }\n });\n context.setProp(context.global, \"__hostCall__\", hostCallFn);\n hostCallFn.dispose();\n }\n\n // Create __nextInstanceId__ function if it doesn't exist\n const existingNextId = context.getProp(context.global, \"__nextInstanceId__\");\n const hasNextId = context.typeof(existingNextId) === \"function\";\n existingNextId.dispose();\n\n if (!hasNextId) {\n const nextIdFn = context.newFunction(\"__nextInstanceId__\", () => {\n return context.newNumber(nextInstanceId());\n });\n context.setProp(context.global, \"__nextInstanceId__\", nextIdFn);\n nextIdFn.dispose();\n }\n\n // Register callbacks for this class\n const callbacks: ClassCallbacks<TState> = {\n construct: definition.construct,\n methods: definition.methods,\n properties: definition.properties,\n staticMethods: definition.staticMethods,\n };\n classCallbackRegistry.set(className, callbacks as unknown as ClassCallbacks<object>);\n\n // Build the JavaScript class code\n let classCode = `(function() {\n const __className__ = ${JSON.stringify(className)};\n\n class ${className} {\n constructor(...args) {\n Object.defineProperty(this, '__instanceId__', {\n value: __nextInstanceId__(),\n enumerable: false,\n writable: false,\n configurable: false\n });\n __hostCall__(__className__, \"__construct__\", this.__instanceId__, ...args);\n }\n`;\n\n // Add methods\n if (definition.methods) {\n for (const methodName of Object.keys(definition.methods)) {\n classCode += `\n ${methodName}(...args) {\n return __hostCall__(__className__, ${JSON.stringify(methodName)}, this.__instanceId__, ...args);\n }\n`;\n }\n }\n\n // Add properties (getters/setters)\n if (definition.properties) {\n for (const [propName, descriptor] of Object.entries(definition.properties)) {\n if (descriptor.get) {\n classCode += `\n get ${propName}() {\n return __hostCall__(__className__, \"get:${propName}\", this.__instanceId__);\n }\n`;\n }\n if (descriptor.set) {\n classCode += `\n set ${propName}(value) {\n __hostCall__(__className__, \"set:${propName}\", this.__instanceId__, value);\n }\n`;\n }\n }\n }\n\n // Close the class definition\n classCode += ` }\n`;\n\n // Add static methods\n if (definition.staticMethods) {\n for (const methodName of Object.keys(definition.staticMethods)) {\n classCode += `\n ${className}.${methodName} = function(...args) {\n return __hostCall__(__className__, \"static:${methodName}\", 0, ...args);\n };\n`;\n }\n }\n\n // Add static properties\n if (definition.staticProperties) {\n for (const [propName, value] of Object.entries(definition.staticProperties)) {\n classCode += `\n ${className}.${propName} = ${JSON.stringify(value)};\n`;\n }\n }\n\n classCode += `\n return ${className};\n})()`;\n\n // Evaluate the class definition\n const result = context.evalCode(classCode);\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to define class ${className}: ${JSON.stringify(error)}`);\n }\n\n // Store reference to instance state in stateMap for backwards compatibility\n // When an instance handle is accessed, we can look up its state via __instanceId__\n const classHandle = result.value;\n\n return classHandle;\n}\n\n// Registry for class callbacks\ninterface ClassCallbacks<TState extends object> {\n construct?: (args: unknown[]) => TState;\n methods?: Record<string, (this: TState, ...args: unknown[]) => unknown>;\n properties?: Record<string, { get?: (this: TState) => unknown; set?: (this: TState, value: unknown) => void }>;\n staticMethods?: Record<string, (...args: unknown[]) => unknown>;\n}\n\nconst classCallbackRegistry = new Map<string, ClassCallbacks<object>>();\n\n/**\n * Get internal state for a QuickJS instance by extracting its __instanceId__\n */\nexport function getInstanceState<T>(\n context: QuickJSContext,\n instanceHandle: QuickJSHandle\n): T | undefined {\n const idHandle = context.getProp(instanceHandle, \"__instanceId__\");\n if (context.typeof(idHandle) !== \"number\") {\n idHandle.dispose();\n return undefined;\n }\n const id = context.getNumber(idHandle);\n idHandle.dispose();\n return getStateById<T>(id);\n}\n\n/**\n * Set internal state for a QuickJS instance by extracting its __instanceId__\n */\nexport function setInstanceState<T>(\n context: QuickJSContext,\n instanceHandle: QuickJSHandle,\n state: T\n): void {\n const idHandle = context.getProp(instanceHandle, \"__instanceId__\");\n if (context.typeof(idHandle) !== \"number\") {\n idHandle.dispose();\n throw new Error(\"Cannot set state: instance has no __instanceId__\");\n }\n const id = context.getNumber(idHandle);\n idHandle.dispose();\n setInstanceStateById(id, state);\n}\n\n/**\n * Get internal state by instance ID directly\n * Useful when you have the instanceId from an unmarshaled object\n */\nexport function getInstanceStateById<T>(instanceId: number): T | undefined {\n return getStateById<T>(instanceId);\n}\n\n/**\n * Clean up instance state when an instance is no longer needed\n */\nexport function cleanupInstanceState(instanceId: number): void {\n cleanupState(instanceId);\n}\n\n/**\n * Clear all instance state (useful for context disposal or testing cleanup)\n */\nexport function clearAllInstanceState(): void {\n clearAllState();\n}\n"
5
+ "import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { ClassDefinition, StateMap } from \"./types.mjs\";\nimport { unmarshal } from \"./unmarshal.mjs\";\nimport { marshal } from \"./marshal.mjs\";\nimport {\n nextInstanceId,\n registerInstance,\n getInstanceStateById as getStateById,\n setInstanceStateById,\n cleanupInstanceState as cleanupState,\n clearAllInstanceState as clearAllState,\n} from \"./instance-state.mjs\";\n\n// ============================================\n// Error Type Preservation\n// ============================================\n\n/**\n * Supported error types for typed error creation.\n */\nconst ERROR_TYPES = [\"TypeError\", \"RangeError\", \"SyntaxError\", \"ReferenceError\", \"URIError\", \"EvalError\"] as const;\n\n/**\n * Create a typed error in the QuickJS context.\n * Gets the error constructor fresh each time to avoid handle lifecycle issues.\n */\nfunction createTypedError(\n context: QuickJSContext,\n error: Error\n): QuickJSHandle {\n if ((ERROR_TYPES as readonly string[]).includes(error.name)) {\n const ctor = context.getProp(context.global, error.name);\n if (context.typeof(ctor) === \"function\") {\n const messageHandle = context.newString(error.message);\n const result = context.callFunction(ctor, context.undefined, messageHandle);\n messageHandle.dispose();\n ctor.dispose();\n\n if (!result.error) {\n return result.value;\n }\n result.error.dispose();\n } else {\n ctor.dispose();\n }\n }\n\n // Fallback to generic Error\n return context.newError(error.message);\n}\n\n/**\n * Create a new StateMap for tracking object internal states\n */\nexport function createStateMap(): StateMap {\n return new WeakMap();\n}\n\n/**\n * Get the internal state associated with a QuickJS object handle\n */\nexport function getState<T extends object>(\n stateMap: StateMap,\n handle: QuickJSHandle\n): T | undefined {\n return stateMap.get(handle) as T | undefined;\n}\n\n/**\n * Set the internal state associated with a QuickJS object handle\n */\nexport function setState<T extends object>(\n stateMap: StateMap,\n handle: QuickJSHandle,\n state: T\n): void {\n stateMap.set(handle, state);\n}\n\n// Instance state is now managed by instance-state.ts\n\n/**\n * Define a class in the QuickJS context\n *\n * Uses evalCode to create a proper JavaScript class that can be called with 'new'.\n * Host-side callbacks are registered and invoked by the JavaScript class.\n *\n * @returns Handle to the class constructor (caller must manage disposal)\n *\n * @example\n * const Point = defineClass(context, stateMap, {\n * name: \"Point\",\n * construct: ([x, y]) => ({ x: Number(x), y: Number(y) }),\n * methods: {\n * distance(this: { x: number; y: number }) {\n * return Math.sqrt(this.x ** 2 + this.y ** 2);\n * }\n * },\n * properties: {\n * x: {\n * get(this: { x: number }) { return this.x; },\n * set(this: { x: number }, v: unknown) { this.x = Number(v); }\n * }\n * }\n * });\n * context.setProp(context.global, \"Point\", Point);\n */\nexport function defineClass<TState extends object>(\n context: QuickJSContext,\n stateMap: StateMap,\n definition: ClassDefinition<TState>\n): QuickJSHandle {\n const className = definition.name;\n\n // Create the __hostCall__ function if it doesn't exist\n const existingHostCall = context.getProp(context.global, \"__hostCall__\");\n const hasHostCall = context.typeof(existingHostCall) === \"function\";\n existingHostCall.dispose();\n\n if (!hasHostCall) {\n const hostCallFn = context.newFunction(\"__hostCall__\", (classNameHandle, actionHandle, instanceIdHandle, ...argHandles) => {\n const classNameStr = context.getString(classNameHandle);\n const action = context.getString(actionHandle);\n const instanceId = context.getNumber(instanceIdHandle);\n const args = argHandles.map((h) => unmarshal(context, h));\n\n const callbacks = classCallbackRegistry.get(classNameStr);\n if (!callbacks) {\n throw context.newError(`No callbacks registered for class ${classNameStr}`);\n }\n\n const state = getStateById<TState>(instanceId);\n\n try {\n let result: unknown;\n\n if (action === \"__construct__\") {\n // Constructor call\n if (callbacks.construct) {\n const newState = callbacks.construct(args);\n // Register instance with className for cross-class access\n registerInstance(instanceId, classNameStr, newState);\n result = undefined;\n }\n } else if (action.startsWith(\"get:\")) {\n // Getter call\n const propName = action.slice(4);\n const getter = callbacks.properties?.[propName]?.get;\n if (getter && state) {\n result = getter.call(state);\n }\n } else if (action.startsWith(\"set:\")) {\n // Setter call\n const propName = action.slice(4);\n const setter = callbacks.properties?.[propName]?.set;\n if (setter && state) {\n setter.call(state, args[0]);\n }\n result = undefined;\n } else if (action.startsWith(\"static:\")) {\n // Static method call\n const methodName = action.slice(7);\n const staticMethod = callbacks.staticMethods?.[methodName];\n if (staticMethod) {\n result = staticMethod(...args);\n }\n } else {\n // Instance method call\n const method = callbacks.methods?.[action];\n if (method && state) {\n result = method.call(state, ...args);\n }\n }\n\n // Handle promises\n if (result instanceof Promise) {\n const deferred = context.newPromise();\n result\n .then((resolved) => {\n const resolvedHandle = marshal(context, resolved);\n deferred.resolve(resolvedHandle);\n resolvedHandle.dispose();\n context.runtime.executePendingJobs();\n })\n .catch((error) => {\n const errorHandle = marshal(\n context,\n error instanceof Error\n ? { name: error.name, message: error.message }\n : { message: String(error) }\n );\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n });\n return deferred.handle;\n }\n\n return marshal(context, result);\n } catch (error) {\n // Preserve error type (TypeError, RangeError, etc.) when re-throwing\n if (error instanceof Error) {\n throw createTypedError(context, error);\n }\n throw context.newError(String(error));\n }\n });\n context.setProp(context.global, \"__hostCall__\", hostCallFn);\n hostCallFn.dispose();\n }\n\n // Create __nextInstanceId__ function if it doesn't exist\n const existingNextId = context.getProp(context.global, \"__nextInstanceId__\");\n const hasNextId = context.typeof(existingNextId) === \"function\";\n existingNextId.dispose();\n\n if (!hasNextId) {\n const nextIdFn = context.newFunction(\"__nextInstanceId__\", () => {\n return context.newNumber(nextInstanceId());\n });\n context.setProp(context.global, \"__nextInstanceId__\", nextIdFn);\n nextIdFn.dispose();\n }\n\n // Register callbacks for this class\n const callbacks: ClassCallbacks<TState> = {\n construct: definition.construct,\n methods: definition.methods,\n properties: definition.properties,\n staticMethods: definition.staticMethods,\n };\n classCallbackRegistry.set(className, callbacks as unknown as ClassCallbacks<object>);\n\n // Build the JavaScript class code\n const hasParent = definition.extends !== undefined;\n\n // If extending a class, temporarily set it as a global so the IIFE can access it\n if (hasParent) {\n context.setProp(context.global, \"__tempParentClass__\", definition.extends!);\n }\n\n let classCode = hasParent\n ? `(function() {\n const __className__ = ${JSON.stringify(className)};\n const __ParentClass__ = __tempParentClass__;\n\n class ${className} extends __ParentClass__ {\n constructor(...args) {\n super();\n // __instanceId__ is already set by parent class, just call our construct\n __hostCall__(__className__, \"__construct__\", this.__instanceId__, ...args);\n }`\n : `(function() {\n const __className__ = ${JSON.stringify(className)};\n\n class ${className} {\n constructor(...args) {\n Object.defineProperty(this, '__instanceId__', {\n value: __nextInstanceId__(),\n enumerable: false,\n writable: false,\n configurable: false\n });\n __hostCall__(__className__, \"__construct__\", this.__instanceId__, ...args);\n }`;\n\n // Add methods\n if (definition.methods) {\n for (const methodName of Object.keys(definition.methods)) {\n classCode += `\n ${methodName}(...args) {\n return __hostCall__(__className__, ${JSON.stringify(methodName)}, this.__instanceId__, ...args);\n }\n`;\n }\n }\n\n // Add properties (getters/setters)\n if (definition.properties) {\n for (const [propName, descriptor] of Object.entries(definition.properties)) {\n if (descriptor.get) {\n classCode += `\n get ${propName}() {\n return __hostCall__(__className__, \"get:${propName}\", this.__instanceId__);\n }\n`;\n }\n if (descriptor.set) {\n classCode += `\n set ${propName}(value) {\n __hostCall__(__className__, \"set:${propName}\", this.__instanceId__, value);\n }\n`;\n }\n }\n }\n\n // Close the class definition\n classCode += ` }\n`;\n\n // Add static methods\n if (definition.staticMethods) {\n for (const methodName of Object.keys(definition.staticMethods)) {\n classCode += `\n ${className}.${methodName} = function(...args) {\n return __hostCall__(__className__, \"static:${methodName}\", 0, ...args);\n };\n`;\n }\n }\n\n // Add static properties\n if (definition.staticProperties) {\n for (const [propName, value] of Object.entries(definition.staticProperties)) {\n classCode += `\n ${className}.${propName} = ${JSON.stringify(value)};\n`;\n }\n }\n\n classCode += `\n return ${className};\n})()`;\n\n // Evaluate the class definition\n const result = context.evalCode(classCode);\n\n // Clean up temporary parent class global if we set one\n if (hasParent) {\n context.setProp(context.global, \"__tempParentClass__\", context.undefined);\n }\n\n if (result.error) {\n const error = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to define class ${className}: ${JSON.stringify(error)}`);\n }\n\n // Store reference to instance state in stateMap for backwards compatibility\n // When an instance handle is accessed, we can look up its state via __instanceId__\n const classHandle = result.value;\n\n return classHandle;\n}\n\n// Registry for class callbacks\ninterface ClassCallbacks<TState extends object> {\n construct?: (args: unknown[]) => TState;\n methods?: Record<string, (this: TState, ...args: unknown[]) => unknown>;\n properties?: Record<string, { get?: (this: TState) => unknown; set?: (this: TState, value: unknown) => void }>;\n staticMethods?: Record<string, (...args: unknown[]) => unknown>;\n}\n\nconst classCallbackRegistry = new Map<string, ClassCallbacks<object>>();\n\n/**\n * Get internal state for a QuickJS instance by extracting its __instanceId__\n */\nexport function getInstanceState<T>(\n context: QuickJSContext,\n instanceHandle: QuickJSHandle\n): T | undefined {\n const idHandle = context.getProp(instanceHandle, \"__instanceId__\");\n if (context.typeof(idHandle) !== \"number\") {\n idHandle.dispose();\n return undefined;\n }\n const id = context.getNumber(idHandle);\n idHandle.dispose();\n return getStateById<T>(id);\n}\n\n/**\n * Set internal state for a QuickJS instance by extracting its __instanceId__\n */\nexport function setInstanceState<T>(\n context: QuickJSContext,\n instanceHandle: QuickJSHandle,\n state: T\n): void {\n const idHandle = context.getProp(instanceHandle, \"__instanceId__\");\n if (context.typeof(idHandle) !== \"number\") {\n idHandle.dispose();\n throw new Error(\"Cannot set state: instance has no __instanceId__\");\n }\n const id = context.getNumber(idHandle);\n idHandle.dispose();\n setInstanceStateById(id, state);\n}\n\n/**\n * Get internal state by instance ID directly\n * Useful when you have the instanceId from an unmarshaled object\n */\nexport function getInstanceStateById<T>(instanceId: number): T | undefined {\n return getStateById<T>(instanceId);\n}\n\n/**\n * Clean up instance state when an instance is no longer needed\n */\nexport function cleanupInstanceState(instanceId: number): void {\n cleanupState(instanceId);\n}\n\n/**\n * Clear all instance state (useful for context disposal or testing cleanup)\n */\nexport function clearAllInstanceState(): void {\n clearAllState();\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "B233FA1A9250E66764756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "1C141B77B235492264756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -25,12 +25,26 @@ function getClassName(value) {
25
25
  }
26
26
  return;
27
27
  }
28
+ function createClassTypeGuard(className) {
29
+ return (value) => {
30
+ return isDefineClassInstance(value) && value.__className__ === className;
31
+ };
32
+ }
33
+ var isUnmarshalledRequest = createClassTypeGuard("Request");
34
+ var isUnmarshalledResponse = createClassTypeGuard("Response");
35
+ var isUnmarshalledHeaders = createClassTypeGuard("Headers");
36
+ var isUnmarshalledFormData = createClassTypeGuard("FormData");
28
37
  export {
38
+ isUnmarshalledResponse,
39
+ isUnmarshalledRequest,
40
+ isUnmarshalledHeaders,
41
+ isUnmarshalledFormData,
29
42
  isInstanceOf,
30
43
  isDefineClassInstance,
31
44
  getInstanceId,
32
45
  getClassName,
33
- getClassInstanceState
46
+ getClassInstanceState,
47
+ createClassTypeGuard
34
48
  };
35
49
 
36
- //# debugId=6528C2D122F7965E64756E2164756E21
50
+ //# debugId=1BCADF98BB77A3C164756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/class-helpers.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Helper functions for working with defineClass instances\n *\n * These helpers enable cross-class state access when class instances\n * are passed between methods (e.g., File to FormData.append).\n */\n\nimport { getInstanceStateById } from \"./instance-state.mjs\";\n\n/**\n * Represents an unmarshalled defineClass instance\n */\nexport interface DefineClassInstance {\n __instanceId__: number;\n __className__: string;\n __isDefineClassInstance__: true;\n}\n\n/**\n * Type guard to check if a value is a defineClass instance\n */\nexport function isDefineClassInstance(\n value: unknown\n): value is DefineClassInstance {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"__isDefineClassInstance__\" in value &&\n (value as DefineClassInstance).__isDefineClassInstance__ === true &&\n \"__instanceId__\" in value &&\n typeof (value as DefineClassInstance).__instanceId__ === \"number\" &&\n \"__className__\" in value &&\n typeof (value as DefineClassInstance).__className__ === \"string\"\n );\n}\n\n/**\n * Check if an unmarshalled value is an instance of a specific class\n *\n * @example\n * if (isInstanceOf(value, \"File\")) {\n * const fileState = getClassInstanceState<FileState>(value);\n * }\n */\nexport function isInstanceOf(value: unknown, className: string): boolean {\n return isDefineClassInstance(value) && value.__className__ === className;\n}\n\n/**\n * Get the internal state of a defineClass instance\n *\n * @example\n * const fileState = getClassInstanceState<FileInternalState>(value);\n * if (fileState) {\n * console.log(fileState.parts, fileState.name);\n * }\n */\nexport function getClassInstanceState<T>(value: unknown): T | undefined {\n if (!isDefineClassInstance(value)) {\n return undefined;\n }\n return getInstanceStateById<T>(value.__instanceId__);\n}\n\n/**\n * Get the instance ID from an unmarshalled value if it's a defineClass instance\n */\nexport function getInstanceId(value: unknown): number | undefined {\n if (isDefineClassInstance(value)) {\n return value.__instanceId__;\n }\n return undefined;\n}\n\n/**\n * Get the class name from an unmarshalled value if it's a defineClass instance\n */\nexport function getClassName(value: unknown): string | undefined {\n if (isDefineClassInstance(value)) {\n return value.__className__;\n }\n return undefined;\n}\n"
5
+ "/**\n * Helper functions for working with defineClass instances\n *\n * These helpers enable cross-class state access when class instances\n * are passed between methods (e.g., File to FormData.append).\n */\n\nimport { getInstanceStateById } from \"./instance-state.mjs\";\n\n/**\n * Represents an unmarshalled defineClass instance\n */\nexport interface DefineClassInstance {\n __instanceId__: number;\n __className__: string;\n __isDefineClassInstance__: true;\n}\n\n/**\n * Type guard to check if a value is a defineClass instance\n */\nexport function isDefineClassInstance(\n value: unknown\n): value is DefineClassInstance {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"__isDefineClassInstance__\" in value &&\n (value as DefineClassInstance).__isDefineClassInstance__ === true &&\n \"__instanceId__\" in value &&\n typeof (value as DefineClassInstance).__instanceId__ === \"number\" &&\n \"__className__\" in value &&\n typeof (value as DefineClassInstance).__className__ === \"string\"\n );\n}\n\n/**\n * Check if an unmarshalled value is an instance of a specific class\n *\n * @example\n * if (isInstanceOf(value, \"File\")) {\n * const fileState = getClassInstanceState<FileState>(value);\n * }\n */\nexport function isInstanceOf(value: unknown, className: string): boolean {\n return isDefineClassInstance(value) && value.__className__ === className;\n}\n\n/**\n * Get the internal state of a defineClass instance\n *\n * @example\n * const fileState = getClassInstanceState<FileInternalState>(value);\n * if (fileState) {\n * console.log(fileState.parts, fileState.name);\n * }\n */\nexport function getClassInstanceState<T>(value: unknown): T | undefined {\n if (!isDefineClassInstance(value)) {\n return undefined;\n }\n return getInstanceStateById<T>(value.__instanceId__);\n}\n\n/**\n * Get the instance ID from an unmarshalled value if it's a defineClass instance\n */\nexport function getInstanceId(value: unknown): number | undefined {\n if (isDefineClassInstance(value)) {\n return value.__instanceId__;\n }\n return undefined;\n}\n\n/**\n * Get the class name from an unmarshalled value if it's a defineClass instance\n */\nexport function getClassName(value: unknown): string | undefined {\n if (isDefineClassInstance(value)) {\n return value.__className__;\n }\n return undefined;\n}\n\n/**\n * Interface for typed class instance with specific class name\n */\nexport interface TypedClassInstance<T extends string> extends DefineClassInstance {\n __className__: T;\n}\n\n/**\n * Create a type guard for a specific class name\n *\n * @example\n * const isRequest = createClassTypeGuard<\"Request\">(\"Request\");\n * if (isRequest(value)) {\n * // value is TypedClassInstance<\"Request\">\n * }\n */\nexport function createClassTypeGuard<T extends string>(\n className: T\n): (value: unknown) => value is TypedClassInstance<T> {\n return (value: unknown): value is TypedClassInstance<T> => {\n return isDefineClassInstance(value) && value.__className__ === className;\n };\n}\n\n/**\n * Pre-built type guard for Request instances\n */\nexport const isUnmarshalledRequest = createClassTypeGuard(\"Request\");\n\n/**\n * Pre-built type guard for Response instances\n */\nexport const isUnmarshalledResponse = createClassTypeGuard(\"Response\");\n\n/**\n * Pre-built type guard for Headers instances\n */\nexport const isUnmarshalledHeaders = createClassTypeGuard(\"Headers\");\n\n/**\n * Pre-built type guard for FormData instances\n */\nexport const isUnmarshalledFormData = createClassTypeGuard(\"FormData\");\n"
6
6
  ],
7
- "mappings": ";;AAOA;AAcO,SAAS,qBAAqB,CACnC,OAC8B;AAAA,EAC9B,OACE,UAAU,QACV,OAAO,UAAU,YACjB,+BAA+B,SAC9B,MAA8B,8BAA8B,QAC7D,oBAAoB,SACpB,OAAQ,MAA8B,mBAAmB,YACzD,mBAAmB,SACnB,OAAQ,MAA8B,kBAAkB;AAAA;AAYrD,SAAS,YAAY,CAAC,OAAgB,WAA4B;AAAA,EACvE,OAAO,sBAAsB,KAAK,KAAK,MAAM,kBAAkB;AAAA;AAY1D,SAAS,qBAAwB,CAAC,OAA+B;AAAA,EACtE,IAAI,CAAC,sBAAsB,KAAK,GAAG;AAAA,IACjC;AAAA,EACF;AAAA,EACA,OAAO,qBAAwB,MAAM,cAAc;AAAA;AAM9C,SAAS,aAAa,CAAC,OAAoC;AAAA,EAChE,IAAI,sBAAsB,KAAK,GAAG;AAAA,IAChC,OAAO,MAAM;AAAA,EACf;AAAA,EACA;AAAA;AAMK,SAAS,YAAY,CAAC,OAAoC;AAAA,EAC/D,IAAI,sBAAsB,KAAK,GAAG;AAAA,IAChC,OAAO,MAAM;AAAA,EACf;AAAA,EACA;AAAA;",
8
- "debugId": "6528C2D122F7965E64756E2164756E21",
7
+ "mappings": ";;AAOA;AAcO,SAAS,qBAAqB,CACnC,OAC8B;AAAA,EAC9B,OACE,UAAU,QACV,OAAO,UAAU,YACjB,+BAA+B,SAC9B,MAA8B,8BAA8B,QAC7D,oBAAoB,SACpB,OAAQ,MAA8B,mBAAmB,YACzD,mBAAmB,SACnB,OAAQ,MAA8B,kBAAkB;AAAA;AAYrD,SAAS,YAAY,CAAC,OAAgB,WAA4B;AAAA,EACvE,OAAO,sBAAsB,KAAK,KAAK,MAAM,kBAAkB;AAAA;AAY1D,SAAS,qBAAwB,CAAC,OAA+B;AAAA,EACtE,IAAI,CAAC,sBAAsB,KAAK,GAAG;AAAA,IACjC;AAAA,EACF;AAAA,EACA,OAAO,qBAAwB,MAAM,cAAc;AAAA;AAM9C,SAAS,aAAa,CAAC,OAAoC;AAAA,EAChE,IAAI,sBAAsB,KAAK,GAAG;AAAA,IAChC,OAAO,MAAM;AAAA,EACf;AAAA,EACA;AAAA;AAMK,SAAS,YAAY,CAAC,OAAoC;AAAA,EAC/D,IAAI,sBAAsB,KAAK,GAAG;AAAA,IAChC,OAAO,MAAM;AAAA,EACf;AAAA,EACA;AAAA;AAmBK,SAAS,oBAAsC,CACpD,WACoD;AAAA,EACpD,OAAO,CAAC,UAAmD;AAAA,IACzD,OAAO,sBAAsB,KAAK,KAAK,MAAM,kBAAkB;AAAA;AAAA;AAO5D,IAAM,wBAAwB,qBAAqB,SAAS;AAK5D,IAAM,yBAAyB,qBAAqB,UAAU;AAK9D,IAAM,wBAAwB,qBAAqB,SAAS;AAK5D,IAAM,yBAAyB,qBAAqB,UAAU;",
8
+ "debugId": "1BCADF98BB77A3C164756E2164756E21",
9
9
  "names": []
10
10
  }