vue-lynx 0.3.0 → 0.4.0

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/README.md CHANGED
@@ -18,6 +18,30 @@ Visit **[vue.lynxjs.org](https://vue.lynxjs.org)** for full documentation, inclu
18
18
  - [Gallery Tutorial](https://vue.lynxjs.org/tutorials/gallery.html)
19
19
  - [Swiper Tutorial](https://vue.lynxjs.org/tutorials/swiper.html)
20
20
 
21
+ ## IDE Setup
22
+
23
+ Install the [Vue Language Features (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) extension for VS Code, or the equivalent for your editor (Zed has built-in Vue support via its Vue extension).
24
+
25
+ Add the following to your `tsconfig.json` (or `jsconfig.json` for JS projects):
26
+
27
+ ```json
28
+ {
29
+ "compilerOptions": {
30
+ "types": ["vue-lynx/types"]
31
+ },
32
+ "vueCompilerOptions": {
33
+ "plugins": ["vue-lynx/types/volar-plugin"]
34
+ }
35
+ }
36
+ ```
37
+
38
+ This enables:
39
+ - Correct prop types and completions for all Lynx elements (`<view>`, `<text>`, `<image>`, etc.)
40
+ - IDE errors when using unsupported event modifiers (`.capture`, `.passive`)
41
+ - Type-checked `global-bind*`, `global-catch*`, and `main-thread-*` props
42
+
43
+ Projects created with `create-vue-lynx` have this pre-configured.
44
+
21
45
  ## Examples
22
46
 
23
47
  See the [`examples/`](examples/) directory for complete working examples:
@@ -16,6 +16,7 @@
16
16
  * SET_WORKLET_EVENT: [11, id, eventType, eventName, workletCtx]
17
17
  * SET_MT_REF: [12, id, refImpl]
18
18
  * INIT_MT_REF: [13, wvid, initValue]
19
+ * SET_SCOPE_ID: [14, id, cssId] // Vue scoped CSS support
19
20
  */
20
21
  export declare const OP: {
21
22
  readonly CREATE: 0;
@@ -32,5 +33,6 @@ export declare const OP: {
32
33
  readonly SET_WORKLET_EVENT: 11;
33
34
  readonly SET_MT_REF: 12;
34
35
  readonly INIT_MT_REF: 13;
36
+ readonly SET_SCOPE_ID: 14;
35
37
  };
36
38
  export type OpCode = (typeof OP)[keyof typeof OP];
@@ -19,6 +19,7 @@
19
19
  * SET_WORKLET_EVENT: [11, id, eventType, eventName, workletCtx]
20
20
  * SET_MT_REF: [12, id, refImpl]
21
21
  * INIT_MT_REF: [13, wvid, initValue]
22
+ * SET_SCOPE_ID: [14, id, cssId] // Vue scoped CSS support
22
23
  */
23
24
  export const OP = {
24
25
  CREATE: 0,
@@ -35,5 +36,6 @@ export const OP = {
35
36
  SET_WORKLET_EVENT: 11,
36
37
  SET_MT_REF: 12,
37
38
  INIT_MT_REF: 13,
39
+ SET_SCOPE_ID: 14,
38
40
  };
39
41
  //# sourceMappingURL=ops.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ops.js","sourceRoot":"","sources":["../src/ops.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,yEAAyE;AACzE,0DAA0D;AAE1D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,YAAY,EAAE,CAAC;IACf,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,EAAE;IACV,iBAAiB,EAAE,EAAE;IACrB,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;CACP,CAAC"}
1
+ {"version":3,"file":"ops.js","sourceRoot":"","sources":["../src/ops.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,yEAAyE;AACzE,0DAA0D;AAE1D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,MAAM,EAAE,CAAC;IACT,WAAW,EAAE,CAAC;IACd,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;IACX,SAAS,EAAE,CAAC;IACZ,YAAY,EAAE,CAAC;IACf,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ,MAAM,EAAE,EAAE;IACV,iBAAiB,EAAE,EAAE;IACrB,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;IACf,YAAY,EAAE,EAAE;CACR,CAAC"}
@@ -12,6 +12,8 @@ function createTypedElement(type, parentComponentUniqueId) {
12
12
  return __CreateImage(parentComponentUniqueId);
13
13
  case 'scroll-view':
14
14
  return __CreateScrollView(parentComponentUniqueId);
15
+ case 'div':
16
+ return __CreateView(parentComponentUniqueId);
15
17
  default:
16
18
  return __CreateElement(type, parentComponentUniqueId);
17
19
  }
@@ -165,6 +167,16 @@ function applyOps(ops) {
165
167
  (0, __WEBPACK_EXTERNAL_MODULE__worklet_apply_js_d7370049__.applyInitMtRef)(wvid, initValue);
166
168
  break;
167
169
  }
170
+ case __WEBPACK_EXTERNAL_MODULE_vue_lynx_internal_ops_dc871e34__.OP.SET_SCOPE_ID:
171
+ {
172
+ const id = ops[i++];
173
+ const cssId = ops[i++];
174
+ const el = __WEBPACK_EXTERNAL_MODULE__element_registry_js_05e5c264__.elements.get(id);
175
+ if (el) __SetCSSId([
176
+ el
177
+ ], cssId);
178
+ break;
179
+ }
168
180
  default:
169
181
  break;
170
182
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-lynx",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "description": "Vue 3 framework for building Lynx apps",
6
6
  "keywords": [
@@ -97,7 +97,7 @@
97
97
  "node": ">=18"
98
98
  },
99
99
  "scripts": {
100
- "build": "(cd internal && npx tsc -p tsconfig.build.json) && (cd runtime && npx rslib build) && (cd main-thread && npx rslib build) && (cd plugin && npx rslib build)",
101
- "dev": "(cd internal && npx tsc -p tsconfig.build.json) && (cd runtime && npx rslib build --watch) & (cd main-thread && npx rslib build --watch) & (cd plugin && npx rslib build --watch)"
100
+ "build": "(cd internal && npx tsc -p tsconfig.build.json) && (cd runtime && npx rslib build) && (cd main-thread && npx rslib build) && (cd plugin && npx rslib build) && (cd types && npx rslib build)",
101
+ "dev": "(cd internal && npx tsc -p tsconfig.build.json) && (cd runtime && npx rslib build --watch) & (cd main-thread && npx rslib build --watch) & (cd plugin && npx rslib build --watch) & (cd types && npx rslib build --watch)"
102
102
  }
103
103
  }
@@ -8,6 +8,25 @@ const LAYERS = {
8
8
  BACKGROUND: 'vue:background',
9
9
  MAIN_THREAD: 'vue:main-thread'
10
10
  };
11
+ function stripVueScopeFromAST(node) {
12
+ if (node.children) {
13
+ let item = node.children.head;
14
+ while(item){
15
+ const next = item.next;
16
+ if ('AttributeSelector' === item.data.type && item.data.name?.name?.startsWith('data-v-')) node.children.remove(item);
17
+ else stripVueScopeFromAST(item.data);
18
+ item = next;
19
+ }
20
+ }
21
+ if (node.prelude) stripVueScopeFromAST(node.prelude);
22
+ if (node.block) stripVueScopeFromAST(node.block);
23
+ }
24
+ const vueScopeStripCSSPlugin = {
25
+ name: 'vue-scope-strip',
26
+ phaseStandard (ast) {
27
+ stripVueScopeFromAST(ast);
28
+ }
29
+ };
11
30
  const _dirname = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname((0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.fileURLToPath)(import.meta.url));
12
31
  function applyCSS(api, options) {
13
32
  const { enableCSSSelector, enableCSSInvalidation } = options;
@@ -48,10 +67,12 @@ function applyCSS(api, options) {
48
67
  chain.plugin(CHAIN_ID.PLUGIN.MINI_CSS_EXTRACT).tap(([pluginOptions])=>[
49
68
  {
50
69
  ...pluginOptions,
51
- enableRemoveCSSScope: true,
70
+ enableRemoveCSSScope: false,
52
71
  enableCSSSelector,
53
72
  enableCSSInvalidation,
54
- cssPlugins: []
73
+ cssPlugins: [
74
+ vueScopeStripCSSPlugin
75
+ ]
55
76
  }
56
77
  ]).init((_, args)=>new CssExtractPlugin(...args)).end().end();
57
78
  function removeLightningCSS(rule, ids) {
@@ -78,6 +99,37 @@ const normalizeCssLoaderOptions = (options, exportOnlyLocals)=>{
78
99
  }
79
100
  return options;
80
101
  };
102
+ const PLUGIN_NAME = 'lynx:vue-scoped-cssid';
103
+ function extractCssIdFromQuery(query) {
104
+ if (!query.includes('type=style') || !query.includes('scoped')) return null;
105
+ if (query.includes('cssId=')) return null;
106
+ const match = query.match(/[?&]id=([a-f0-9]+)/);
107
+ if (!match) return null;
108
+ return 0x7fffffff & Number.parseInt(match[1], 16);
109
+ }
110
+ class VueScopedCSSIdPlugin {
111
+ apply(compiler) {
112
+ compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation)=>{
113
+ const NormalModule = compiler.webpack?.NormalModule;
114
+ if (!NormalModule?.getCompilationHooks) return;
115
+ NormalModule.getCompilationHooks(compilation).loader.tap(PLUGIN_NAME, (loaderContext)=>{
116
+ const query = loaderContext.resourceQuery ?? '';
117
+ const cssId = extractCssIdFromQuery(query);
118
+ if (null === cssId) return;
119
+ const newQuery = query + `&cssId=${cssId}`;
120
+ try {
121
+ Object.defineProperty(loaderContext, 'resourceQuery', {
122
+ value: newQuery,
123
+ writable: true,
124
+ configurable: true
125
+ });
126
+ } catch {
127
+ loaderContext.resourceQuery = newQuery;
128
+ }
129
+ });
130
+ });
131
+ }
132
+ }
81
133
  const PLUGIN_TEMPLATE = 'lynx:vue-template';
82
134
  const PLUGIN_RUNTIME_WRAPPER = 'lynx:vue-runtime-wrapper';
83
135
  const PLUGIN_ENCODE = 'lynx:vue-encode';
@@ -124,7 +176,7 @@ class VueCSSConfigPlugin {
124
176
  const hooks = __WEBPACK_EXTERNAL_MODULE__lynx_js_template_webpack_plugin_e98d2f08__.LynxTemplatePlugin.getLynxTemplatePluginHooks(compilation);
125
177
  hooks.beforeEncode.tap(PLUGIN_CSS_CONFIG, (args)=>{
126
178
  const encodeData = args['encodeData'];
127
- Object.assign(encodeData.compilerOptions, this.compilerOptions);
179
+ Object.assign(encodeData.sourceContent.config, this.compilerOptions);
128
180
  return args;
129
181
  });
130
182
  });
@@ -270,10 +322,12 @@ function applyEntry(api, opts = {}) {
270
322
  enableCSSInvalidation: opts.enableCSSSelector ?? true,
271
323
  enableCSSInheritance: opts.enableCSSInheritance ?? false,
272
324
  customCSSInheritanceList: opts.customCSSInheritanceList,
273
- enableRemoveCSSScope: true,
325
+ enableRemoveCSSScope: false,
274
326
  enableNewGesture: false,
275
327
  removeDescendantSelectorScope: true,
276
- cssPlugins: []
328
+ cssPlugins: [
329
+ vueScopeStripCSSPlugin
330
+ ]
277
331
  }
278
332
  ]).end();
279
333
  }
@@ -281,6 +335,7 @@ function applyEntry(api, opts = {}) {
281
335
  if ((isLynx || isWeb) && mainThreadFilenames.length > 0) chain.plugin(PLUGIN_MARK_MAIN_THREAD).use(VueMarkMainThreadPlugin, [
282
336
  mainThreadFilenames
283
337
  ]).end();
338
+ if (isLynx || isWeb) chain.plugin('lynx:vue-scoped-cssid').use(VueScopedCSSIdPlugin, []).end();
284
339
  if (isLynx) {
285
340
  const cssConfigOptions = {};
286
341
  if (opts.enableCSSInlineVariables) cssConfigOptions['enableCSSInlineVariables'] = true;
@@ -287,6 +287,22 @@ export { onRenderTracked } from '@vue/runtime-core';
287
287
  * @public
288
288
  */
289
289
  export { onRenderTriggered } from '@vue/runtime-core';
290
+ /**
291
+ * Registers a hook to be called when the component is inserted into the DOM
292
+ * as part of a tree cached by `<KeepAlive>`.
293
+ *
294
+ * @see {@link https://vuejs.org/api/composition-api-lifecycle.html#onactivated | Vue docs}
295
+ * @public
296
+ */
297
+ export { onActivated } from '@vue/runtime-core';
298
+ /**
299
+ * Registers a hook to be called when the component is removed from the DOM
300
+ * as part of a tree cached by `<KeepAlive>`.
301
+ *
302
+ * @see {@link https://vuejs.org/api/composition-api-lifecycle.html#ondeactivated | Vue docs}
303
+ * @public
304
+ */
305
+ export { onDeactivated } from '@vue/runtime-core';
290
306
  /**
291
307
  * Watches one or more reactive data sources and invokes a callback when the sources change.
292
308
  *
@@ -504,6 +520,13 @@ export { Fragment } from '@vue/runtime-core';
504
520
  * @public
505
521
  */
506
522
  export { Suspense } from '@vue/runtime-core';
523
+ /**
524
+ * Caches dynamically toggled components, preserving their state when inactive.
525
+ *
526
+ * @see {@link https://vuejs.org/api/built-in-components.html#keepalive | Vue docs}
527
+ * @public
528
+ */
529
+ export { KeepAlive } from '@vue/runtime-core';
507
530
  /**
508
531
  * Vue's version string.
509
532
  *
@@ -517,6 +540,15 @@ export { version } from '@vue/runtime-core';
517
540
  * @public
518
541
  */
519
542
  export { mergeProps } from '@vue/runtime-core';
543
+ /**
544
+ * Emitted by the template compiler for `v-once` subtrees. Disables block
545
+ * tracking during the initial render so the cached VNode is never added to a
546
+ * parent block's dynamic children array — ensuring the patcher skips it on
547
+ * every subsequent render and no ops reach the main thread.
548
+ *
549
+ * @public
550
+ */
551
+ export { setBlockTracking } from '@vue/runtime-core';
520
552
  /** @hidden */ export { createBlock } from '@vue/runtime-core';
521
553
  /** @hidden */ export { createElementBlock } from '@vue/runtime-core';
522
554
  /** @hidden */ export { createVNode } from '@vue/runtime-core';
@@ -539,21 +571,41 @@ export { mergeProps } from '@vue/runtime-core';
539
571
  /** @hidden */ export { withCtx } from '@vue/runtime-core';
540
572
  /** @hidden */ export { renderSlot } from '@vue/runtime-core';
541
573
  /** @hidden */ export { createSlots } from '@vue/runtime-core';
542
- /** @hidden */ export { setBlockTracking } from '@vue/runtime-core';
543
574
  /** @hidden */ export { pushScopeId } from '@vue/runtime-core';
544
575
  /** @hidden */ export { popScopeId } from '@vue/runtime-core';
545
576
  /** @hidden */ export { withScopeId } from '@vue/runtime-core';
546
577
  /** @hidden */ export { toHandlerKey } from '@vue/runtime-core';
547
578
  /** @hidden */ export { toHandlers } from '@vue/runtime-core';
548
579
  /** @hidden */ export { withMemo } from '@vue/runtime-core';
580
+ /** @hidden */ export { isMemoSame } from '@vue/runtime-core';
549
581
  /** @hidden */ export { guardReactiveProps } from '@vue/runtime-core';
550
582
  /** @hidden */ export { withAsyncContext } from '@vue/runtime-core';
551
583
  /** @hidden */ export { Text } from '@vue/runtime-core';
552
584
  /** @hidden */ export { Comment } from '@vue/runtime-core';
585
+ export { Teleport } from '@vue/runtime-core';
553
586
  export declare const vModelText: ObjectDirective<ShadowElement>;
554
587
  export declare const vModelCheckbox: ObjectDirective;
555
588
  export declare const vModelSelect: ObjectDirective;
556
589
  export declare const vModelRadio: ObjectDirective;
590
+ /**
591
+ * Wraps an event handler with Lynx event modifiers.
592
+ *
593
+ * Supported modifiers:
594
+ * - `.once` — handler is invoked at most once; subsequent events are ignored
595
+ * - `.stop` — registers the event as `catchEvent` (native Lynx stop-propagation)
596
+ * and also calls `event.stopPropagation()` for DOM environments
597
+ * - `.prevent` — accepted for code portability; no-op on Lynx (no browser default actions exist)
598
+ * - `.self` — skips the handler unless the event target is the listener element
599
+ *
600
+ * The wrapped function is cached on `fn._withMods` keyed by the modifier
601
+ * string so that stable function references survive re-renders.
602
+ *
603
+ * `.stop` sets `_lynxCatch = true` on the wrapper so that `patchProp` can
604
+ * register the event as `catchEvent` — the native Lynx mechanism for stopping
605
+ * event bubbling. Calling `stopPropagation()` at the JS level alone is not
606
+ * sufficient because native Lynx bubbling is decided before JS handlers run.
607
+ */
608
+ export declare function withModifiers(fn: (...args: unknown[]) => unknown, modifiers: string[]): (...args: unknown[]) => unknown;
557
609
  export { Transition, TransitionGroup };
558
610
  /** @hidden */
559
611
  export { nodeOps };
@@ -70,18 +70,6 @@ function createStaticVNode(_content, _numberOfNodes) {
70
70
  throw new Error("[vue-lynx] createStaticVNode is not supported \u2014 the Lynx renderer does not implement insertStaticContent.");
71
71
  }
72
72
  const Static = Symbol.for('v-stc');
73
- function KeepAlive() {
74
- if (__DEV__) console.warn("[vue-lynx] KeepAlive is not supported \u2014 Lynx renderer has no element recycling.");
75
- }
76
- function onActivated(_fn) {
77
- if (__DEV__) console.warn("[vue-lynx] onActivated is not supported \u2014 KeepAlive is not available.");
78
- }
79
- function onDeactivated(_fn) {
80
- if (__DEV__) console.warn("[vue-lynx] onDeactivated is not supported \u2014 KeepAlive is not available.");
81
- }
82
- function Teleport() {
83
- if (__DEV__) console.warn("[vue-lynx] Teleport is not supported \u2014 Lynx renderer has no querySelector.");
84
- }
85
73
  function looseToNumber(val) {
86
74
  const n = Number.parseFloat(val);
87
75
  return isNaN(n) ? val : n;
@@ -160,8 +148,41 @@ const vModelUnsupported = {
160
148
  const vModelCheckbox = vModelUnsupported;
161
149
  const vModelSelect = vModelUnsupported;
162
150
  const vModelRadio = vModelUnsupported;
163
- function withModifiers(fn, _modifiers) {
164
- return fn;
151
+ const lynxModifierSideEffects = {
152
+ stop: (e)=>e.stopPropagation?.()
153
+ };
154
+ const lynxModifierGuards = {
155
+ self: (e)=>{
156
+ const t = e.target;
157
+ const ct = e.currentTarget;
158
+ if (null != t && 'number' == typeof t.uid && null != ct && 'number' == typeof ct.uid) return t.uid !== ct.uid;
159
+ if (null != t && 'number' == typeof t.uniqueId && null != ct && 'number' == typeof ct.uniqueId) return t.uniqueId !== ct.uniqueId;
160
+ return e.target !== e.currentTarget;
161
+ }
162
+ };
163
+ function withModifiers(fn, modifiers) {
164
+ if (!fn) return fn;
165
+ const fnAny = fn;
166
+ const cache = fnAny._withMods ?? (fnAny._withMods = {});
167
+ const cacheKey = modifiers.join('.');
168
+ if (cache[cacheKey]) return cache[cacheKey];
169
+ const hasOnce = modifiers.includes('once');
170
+ let called = false;
171
+ const wrapped = (event, ...args)=>{
172
+ if (hasOnce && called) return;
173
+ const e = event;
174
+ for (const mod of modifiers){
175
+ if ('once' === mod) continue;
176
+ const guard = lynxModifierGuards[mod];
177
+ if (guard?.(e)) return;
178
+ lynxModifierSideEffects[mod]?.(e);
179
+ }
180
+ if (hasOnce) called = true;
181
+ return fn(event, ...args);
182
+ };
183
+ if (modifiers.includes('stop')) wrapped._lynxCatch = true;
184
+ cache[cacheKey] = wrapped;
185
+ return wrapped;
165
186
  }
166
187
  function withKeys(fn, _keys) {
167
188
  return fn;
@@ -178,9 +199,11 @@ function resetForTesting() {
178
199
  }
179
200
  var __webpack_exports__Comment = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.Comment;
180
201
  var __webpack_exports__Fragment = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.Fragment;
202
+ var __webpack_exports__KeepAlive = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.KeepAlive;
181
203
  var __webpack_exports__MainThreadRef = __WEBPACK_EXTERNAL_MODULE__main_thread_ref_js_622e3a2a__.MainThreadRef;
182
204
  var __webpack_exports__ShadowElement = __WEBPACK_EXTERNAL_MODULE__shadow_element_js_9ed96a55__.ShadowElement;
183
205
  var __webpack_exports__Suspense = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.Suspense;
206
+ var __webpack_exports__Teleport = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.Teleport;
184
207
  var __webpack_exports__Text = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.Text;
185
208
  var __webpack_exports__Transition = __WEBPACK_EXTERNAL_MODULE__Transition_js_7757bed1__.Transition;
186
209
  var __webpack_exports__TransitionGroup = __WEBPACK_EXTERNAL_MODULE__TransitionGroup_js_57fa4188__.TransitionGroup;
@@ -212,6 +235,7 @@ var __webpack_exports__guardReactiveProps = __WEBPACK_EXTERNAL_MODULE__vue_runti
212
235
  var __webpack_exports__h = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.h;
213
236
  var __webpack_exports__hasInjectionContext = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.hasInjectionContext;
214
237
  var __webpack_exports__inject = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.inject;
238
+ var __webpack_exports__isMemoSame = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.isMemoSame;
215
239
  var __webpack_exports__isProxy = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.isProxy;
216
240
  var __webpack_exports__isReactive = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.isReactive;
217
241
  var __webpack_exports__isReadonly = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.isReadonly;
@@ -224,9 +248,11 @@ var __webpack_exports__nodeOps = __WEBPACK_EXTERNAL_MODULE__node_ops_js_cd9e4a71
224
248
  var __webpack_exports__normalizeClass = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.normalizeClass;
225
249
  var __webpack_exports__normalizeProps = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.normalizeProps;
226
250
  var __webpack_exports__normalizeStyle = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.normalizeStyle;
251
+ var __webpack_exports__onActivated = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.onActivated;
227
252
  var __webpack_exports__onBeforeMount = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.onBeforeMount;
228
253
  var __webpack_exports__onBeforeUnmount = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.onBeforeUnmount;
229
254
  var __webpack_exports__onBeforeUpdate = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.onBeforeUpdate;
255
+ var __webpack_exports__onDeactivated = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.onDeactivated;
230
256
  var __webpack_exports__onErrorCaptured = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.onErrorCaptured;
231
257
  var __webpack_exports__onMounted = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.onMounted;
232
258
  var __webpack_exports__onRenderTracked = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.onRenderTracked;
@@ -282,4 +308,4 @@ var __webpack_exports__withDefaults = __WEBPACK_EXTERNAL_MODULE__vue_runtime_cor
282
308
  var __webpack_exports__withDirectives = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.withDirectives;
283
309
  var __webpack_exports__withMemo = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.withMemo;
284
310
  var __webpack_exports__withScopeId = __WEBPACK_EXTERNAL_MODULE__vue_runtime_core_f9f3aead__.withScopeId;
285
- export { KeepAlive, Static, Teleport, _render, createApp, createStaticVNode, nextTick, onActivated, onDeactivated, onServerPrefetch, resetForTesting, useSSRContext, vModelCheckbox, vModelRadio, vModelSelect, vModelText, vShow, withKeys, withModifiers, __webpack_exports__Comment as Comment, __webpack_exports__Fragment as Fragment, __webpack_exports__MainThreadRef as MainThreadRef, __webpack_exports__ShadowElement as ShadowElement, __webpack_exports__Suspense as Suspense, __webpack_exports__Text as Text, __webpack_exports__Transition as Transition, __webpack_exports__TransitionGroup as TransitionGroup, __webpack_exports__camelize as camelize, __webpack_exports__capitalize as capitalize, __webpack_exports__cloneVNode as cloneVNode, __webpack_exports__computed as computed, __webpack_exports__createBlock as createBlock, __webpack_exports__createCommentVNode as createCommentVNode, __webpack_exports__createElementBlock as createElementBlock, __webpack_exports__createElementVNode as createElementVNode, __webpack_exports__createPageRoot as createPageRoot, __webpack_exports__createSlots as createSlots, __webpack_exports__createTextVNode as createTextVNode, __webpack_exports__createVNode as createVNode, __webpack_exports__customRef as customRef, __webpack_exports__defineAsyncComponent as defineAsyncComponent, __webpack_exports__defineComponent as defineComponent, __webpack_exports__defineEmits as defineEmits, __webpack_exports__defineExpose as defineExpose, __webpack_exports__defineModel as defineModel, __webpack_exports__defineOptions as defineOptions, __webpack_exports__defineProps as defineProps, __webpack_exports__defineSlots as defineSlots, __webpack_exports__effectScope as effectScope, __webpack_exports__getCurrentInstance as getCurrentInstance, __webpack_exports__getCurrentScope as getCurrentScope, __webpack_exports__guardReactiveProps as guardReactiveProps, __webpack_exports__h as h, __webpack_exports__hasInjectionContext as hasInjectionContext, __webpack_exports__inject as inject, __webpack_exports__isProxy as isProxy, __webpack_exports__isReactive as isReactive, __webpack_exports__isReadonly as isReadonly, __webpack_exports__isRef as isRef, __webpack_exports__isShallow as isShallow, __webpack_exports__isVNode as isVNode, __webpack_exports__markRaw as markRaw, __webpack_exports__mergeProps as mergeProps, __webpack_exports__nodeOps as nodeOps, __webpack_exports__normalizeClass as normalizeClass, __webpack_exports__normalizeProps as normalizeProps, __webpack_exports__normalizeStyle as normalizeStyle, __webpack_exports__onBeforeMount as onBeforeMount, __webpack_exports__onBeforeUnmount as onBeforeUnmount, __webpack_exports__onBeforeUpdate as onBeforeUpdate, __webpack_exports__onErrorCaptured as onErrorCaptured, __webpack_exports__onMounted as onMounted, __webpack_exports__onRenderTracked as onRenderTracked, __webpack_exports__onRenderTriggered as onRenderTriggered, __webpack_exports__onScopeDispose as onScopeDispose, __webpack_exports__onUnmounted as onUnmounted, __webpack_exports__onUpdated as onUpdated, __webpack_exports__onWatcherCleanup as onWatcherCleanup, __webpack_exports__openBlock as openBlock, __webpack_exports__popScopeId as popScopeId, __webpack_exports__provide as provide, __webpack_exports__pushScopeId as pushScopeId, __webpack_exports__reactive as reactive, __webpack_exports__readonly as readonly, __webpack_exports__ref as ref, __webpack_exports__renderList as renderList, __webpack_exports__renderSlot as renderSlot, __webpack_exports__resolveComponent as resolveComponent, __webpack_exports__resolveDirective as resolveDirective, __webpack_exports__resolveDynamicComponent as resolveDynamicComponent, __webpack_exports__runOnBackground as runOnBackground, __webpack_exports__runOnMainThread as runOnMainThread, __webpack_exports__setBlockTracking as setBlockTracking, __webpack_exports__shallowReactive as shallowReactive, __webpack_exports__shallowReadonly as shallowReadonly, __webpack_exports__shallowRef as shallowRef, __webpack_exports__takeOps as takeOps, __webpack_exports__toDisplayString as toDisplayString, __webpack_exports__toHandlerKey as toHandlerKey, __webpack_exports__toHandlers as toHandlers, __webpack_exports__toRaw as toRaw, __webpack_exports__toRef as toRef, __webpack_exports__toRefs as toRefs, __webpack_exports__toValue as toValue, __webpack_exports__transformToWorklet as transformToWorklet, __webpack_exports__triggerRef as triggerRef, __webpack_exports__unref as unref, __webpack_exports__useAttrs as useAttrs, __webpack_exports__useCssVars as useCssVars, __webpack_exports__useId as useId, __webpack_exports__useMainThreadRef as useMainThreadRef, __webpack_exports__useModel as useModel, __webpack_exports__useSlots as useSlots, __webpack_exports__useTemplateRef as useTemplateRef, __webpack_exports__version as version, __webpack_exports__watch as watch, __webpack_exports__watchEffect as watchEffect, __webpack_exports__watchPostEffect as watchPostEffect, __webpack_exports__watchSyncEffect as watchSyncEffect, __webpack_exports__withAsyncContext as withAsyncContext, __webpack_exports__withCtx as withCtx, __webpack_exports__withDefaults as withDefaults, __webpack_exports__withDirectives as withDirectives, __webpack_exports__withMemo as withMemo, __webpack_exports__withScopeId as withScopeId };
311
+ export { Static, _render, createApp, createStaticVNode, nextTick, onServerPrefetch, resetForTesting, useSSRContext, vModelCheckbox, vModelRadio, vModelSelect, vModelText, vShow, withKeys, withModifiers, __webpack_exports__Comment as Comment, __webpack_exports__Fragment as Fragment, __webpack_exports__KeepAlive as KeepAlive, __webpack_exports__MainThreadRef as MainThreadRef, __webpack_exports__ShadowElement as ShadowElement, __webpack_exports__Suspense as Suspense, __webpack_exports__Teleport as Teleport, __webpack_exports__Text as Text, __webpack_exports__Transition as Transition, __webpack_exports__TransitionGroup as TransitionGroup, __webpack_exports__camelize as camelize, __webpack_exports__capitalize as capitalize, __webpack_exports__cloneVNode as cloneVNode, __webpack_exports__computed as computed, __webpack_exports__createBlock as createBlock, __webpack_exports__createCommentVNode as createCommentVNode, __webpack_exports__createElementBlock as createElementBlock, __webpack_exports__createElementVNode as createElementVNode, __webpack_exports__createPageRoot as createPageRoot, __webpack_exports__createSlots as createSlots, __webpack_exports__createTextVNode as createTextVNode, __webpack_exports__createVNode as createVNode, __webpack_exports__customRef as customRef, __webpack_exports__defineAsyncComponent as defineAsyncComponent, __webpack_exports__defineComponent as defineComponent, __webpack_exports__defineEmits as defineEmits, __webpack_exports__defineExpose as defineExpose, __webpack_exports__defineModel as defineModel, __webpack_exports__defineOptions as defineOptions, __webpack_exports__defineProps as defineProps, __webpack_exports__defineSlots as defineSlots, __webpack_exports__effectScope as effectScope, __webpack_exports__getCurrentInstance as getCurrentInstance, __webpack_exports__getCurrentScope as getCurrentScope, __webpack_exports__guardReactiveProps as guardReactiveProps, __webpack_exports__h as h, __webpack_exports__hasInjectionContext as hasInjectionContext, __webpack_exports__inject as inject, __webpack_exports__isMemoSame as isMemoSame, __webpack_exports__isProxy as isProxy, __webpack_exports__isReactive as isReactive, __webpack_exports__isReadonly as isReadonly, __webpack_exports__isRef as isRef, __webpack_exports__isShallow as isShallow, __webpack_exports__isVNode as isVNode, __webpack_exports__markRaw as markRaw, __webpack_exports__mergeProps as mergeProps, __webpack_exports__nodeOps as nodeOps, __webpack_exports__normalizeClass as normalizeClass, __webpack_exports__normalizeProps as normalizeProps, __webpack_exports__normalizeStyle as normalizeStyle, __webpack_exports__onActivated as onActivated, __webpack_exports__onBeforeMount as onBeforeMount, __webpack_exports__onBeforeUnmount as onBeforeUnmount, __webpack_exports__onBeforeUpdate as onBeforeUpdate, __webpack_exports__onDeactivated as onDeactivated, __webpack_exports__onErrorCaptured as onErrorCaptured, __webpack_exports__onMounted as onMounted, __webpack_exports__onRenderTracked as onRenderTracked, __webpack_exports__onRenderTriggered as onRenderTriggered, __webpack_exports__onScopeDispose as onScopeDispose, __webpack_exports__onUnmounted as onUnmounted, __webpack_exports__onUpdated as onUpdated, __webpack_exports__onWatcherCleanup as onWatcherCleanup, __webpack_exports__openBlock as openBlock, __webpack_exports__popScopeId as popScopeId, __webpack_exports__provide as provide, __webpack_exports__pushScopeId as pushScopeId, __webpack_exports__reactive as reactive, __webpack_exports__readonly as readonly, __webpack_exports__ref as ref, __webpack_exports__renderList as renderList, __webpack_exports__renderSlot as renderSlot, __webpack_exports__resolveComponent as resolveComponent, __webpack_exports__resolveDirective as resolveDirective, __webpack_exports__resolveDynamicComponent as resolveDynamicComponent, __webpack_exports__runOnBackground as runOnBackground, __webpack_exports__runOnMainThread as runOnMainThread, __webpack_exports__setBlockTracking as setBlockTracking, __webpack_exports__shallowReactive as shallowReactive, __webpack_exports__shallowReadonly as shallowReadonly, __webpack_exports__shallowRef as shallowRef, __webpack_exports__takeOps as takeOps, __webpack_exports__toDisplayString as toDisplayString, __webpack_exports__toHandlerKey as toHandlerKey, __webpack_exports__toHandlers as toHandlers, __webpack_exports__toRaw as toRaw, __webpack_exports__toRef as toRef, __webpack_exports__toRefs as toRefs, __webpack_exports__toValue as toValue, __webpack_exports__transformToWorklet as transformToWorklet, __webpack_exports__triggerRef as triggerRef, __webpack_exports__unref as unref, __webpack_exports__useAttrs as useAttrs, __webpack_exports__useCssVars as useCssVars, __webpack_exports__useId as useId, __webpack_exports__useMainThreadRef as useMainThreadRef, __webpack_exports__useModel as useModel, __webpack_exports__useSlots as useSlots, __webpack_exports__useTemplateRef as useTemplateRef, __webpack_exports__version as version, __webpack_exports__watch as watch, __webpack_exports__watchEffect as watchEffect, __webpack_exports__watchPostEffect as watchPostEffect, __webpack_exports__watchSyncEffect as watchSyncEffect, __webpack_exports__withAsyncContext as withAsyncContext, __webpack_exports__withCtx as withCtx, __webpack_exports__withDefaults as withDefaults, __webpack_exports__withDirectives as withDirectives, __webpack_exports__withMemo as withMemo, __webpack_exports__withScopeId as withScopeId };
@@ -2,6 +2,7 @@ import * as __WEBPACK_EXTERNAL_MODULE__event_registry_js_10968c87__ from "./even
2
2
  import * as __WEBPACK_EXTERNAL_MODULE__flush_js_a3609ebe__ from "./flush.js";
3
3
  import * as __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__ from "./ops.js";
4
4
  import * as __WEBPACK_EXTERNAL_MODULE__run_on_background_js_729d321a__ from "./run-on-background.js";
5
+ import * as __WEBPACK_EXTERNAL_MODULE__scope_bridge_js_bd9512e9__ from "./scope-bridge.js";
5
6
  import * as __WEBPACK_EXTERNAL_MODULE__shadow_element_js_9ed96a55__ from "./shadow-element.js";
6
7
  const DIMENSIONLESS = new Set([
7
8
  'flex',
@@ -34,30 +35,50 @@ function normalizeStyle(style) {
34
35
  function parseEventProp(key) {
35
36
  if (key.startsWith('global-bind')) return {
36
37
  type: 'bindGlobalEvent',
37
- name: key.slice(11)
38
+ name: key.slice(11),
39
+ once: false
38
40
  };
39
41
  if (key.startsWith('global-catch')) return {
40
42
  type: 'catchGlobalEvent',
41
- name: key.slice(12)
43
+ name: key.slice(12),
44
+ once: false
42
45
  };
43
46
  if (key.startsWith('catch')) return {
44
47
  type: 'catchEvent',
45
- name: key.slice(5)
48
+ name: key.slice(5),
49
+ once: false
46
50
  };
47
51
  if (/^bind(?!ingx)/.test(key)) return {
48
52
  type: 'bindEvent',
49
- name: key.slice(4)
53
+ name: key.slice(4),
54
+ once: false
50
55
  };
51
56
  if (/^on[A-Z]/.test(key)) {
52
- const name = key.slice(2, 3).toLowerCase() + key.slice(3);
57
+ let name = key.slice(2, 3).toLowerCase() + key.slice(3);
58
+ let once = false;
59
+ if (name.endsWith('Once')) {
60
+ name = name.slice(0, -4);
61
+ once = true;
62
+ }
53
63
  return {
54
64
  type: 'bindEvent',
55
- name
65
+ name,
66
+ once
56
67
  };
57
68
  }
58
69
  return null;
59
70
  }
60
71
  const elementEventSigns = new Map();
72
+ const onceWrappers = new Map();
73
+ const idRegistry = new Map();
74
+ function cleanupIds(el) {
75
+ if (el._id) idRegistry.delete(el._id);
76
+ let child = el.firstChild;
77
+ while(child){
78
+ cleanupIds(child);
79
+ child = child.next;
80
+ }
81
+ }
61
82
  function resolveClass(el) {
62
83
  if (0 === el._transitionClasses.size) return el._baseClass;
63
84
  const parts = [];
@@ -93,12 +114,14 @@ const nodeOps = {
93
114
  while(el.firstChild){
94
115
  const child = el.firstChild;
95
116
  el.removeChild(child);
117
+ cleanupIds(child);
96
118
  (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.REMOVE, el.id, child.id);
97
119
  }
98
120
  (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_TEXT, el.id, text);
99
121
  (0, __WEBPACK_EXTERNAL_MODULE__flush_js_a3609ebe__.scheduleFlush)();
100
122
  },
101
123
  insert (child, parent, anchor) {
124
+ if (child.parent && child.parent !== parent) (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.REMOVE, child.parent.id, child.id);
102
125
  parent.insertBefore(child, anchor ?? null);
103
126
  if ('list' === parent.type && ('#comment' === child.type || '#text' === child.type)) return;
104
127
  let resolvedAnchor = anchor ?? null;
@@ -108,9 +131,10 @@ const nodeOps = {
108
131
  (0, __WEBPACK_EXTERNAL_MODULE__flush_js_a3609ebe__.scheduleFlush)();
109
132
  },
110
133
  remove (child) {
111
- if (child.parent) {
134
+ if (child?.parent) {
112
135
  const parentId = child.parent.id;
113
136
  child.parent.removeChild(child);
137
+ cleanupIds(child);
114
138
  (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.REMOVE, parentId, child.id);
115
139
  (0, __WEBPACK_EXTERNAL_MODULE__flush_js_a3609ebe__.scheduleFlush)();
116
140
  }
@@ -136,17 +160,42 @@ const nodeOps = {
136
160
  const oldSign = signs?.get(key);
137
161
  if (null != nextValue) {
138
162
  const handler = nextValue;
139
- if (oldSign) (0, __WEBPACK_EXTERNAL_MODULE__event_registry_js_10968c87__.updateHandler)(oldSign, handler);
163
+ if (event.once) if (oldSign) {
164
+ const wrapper = onceWrappers.get(oldSign);
165
+ if (wrapper) wrapper.inner = handler;
166
+ } else {
167
+ const wrapper = {
168
+ called: false,
169
+ inner: handler
170
+ };
171
+ const onceHandler = (data)=>{
172
+ if (wrapper.called) return;
173
+ wrapper.called = true;
174
+ wrapper.inner(data);
175
+ };
176
+ const sign = (0, __WEBPACK_EXTERNAL_MODULE__event_registry_js_10968c87__.register)(onceHandler);
177
+ onceWrappers.set(sign, wrapper);
178
+ if (!signs) {
179
+ signs = new Map();
180
+ elementEventSigns.set(el.id, signs);
181
+ }
182
+ signs.set(key, sign);
183
+ const onceEventType = handler._lynxCatch ? 'catchEvent' : event.type;
184
+ (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_EVENT, el.id, onceEventType, event.name, sign);
185
+ }
186
+ else if (oldSign) (0, __WEBPACK_EXTERNAL_MODULE__event_registry_js_10968c87__.updateHandler)(oldSign, handler);
140
187
  else {
188
+ const eventType = handler._lynxCatch ? 'catchEvent' : event.type;
141
189
  const sign = (0, __WEBPACK_EXTERNAL_MODULE__event_registry_js_10968c87__.register)(handler);
142
190
  if (!signs) {
143
191
  signs = new Map();
144
192
  elementEventSigns.set(el.id, signs);
145
193
  }
146
194
  signs.set(key, sign);
147
- (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_EVENT, el.id, event.type, event.name, sign);
195
+ (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_EVENT, el.id, eventType, event.name, sign);
148
196
  }
149
197
  } else if (oldSign) {
198
+ onceWrappers.delete(oldSign);
150
199
  (0, __WEBPACK_EXTERNAL_MODULE__event_registry_js_10968c87__.unregister)(oldSign);
151
200
  signs.delete(key);
152
201
  (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.REMOVE_EVENT, el.id, event.type, event.name);
@@ -163,8 +212,17 @@ const nodeOps = {
163
212
  el._baseClass = nextValue ?? '';
164
213
  const finalClass = resolveClass(el);
165
214
  (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_CLASS, el.id, finalClass);
166
- } else if ('id' === key) (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_ID, el.id, nextValue);
167
- else (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_PROP, el.id, key, nextValue);
215
+ } else if ('id' === key) {
216
+ if (el._id) idRegistry.delete(el._id);
217
+ el._id = null != nextValue ? String(nextValue) : void 0;
218
+ if (__DEV__ && el._id && idRegistry.has(el._id) && idRegistry.get(el._id) !== el) console.warn(`[vue-lynx] Duplicate id "${el._id}" detected. Teleport target resolution may be unreliable.`);
219
+ if (el._id) idRegistry.set(el._id, el);
220
+ (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_ID, el.id, nextValue);
221
+ } else (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_PROP, el.id, key, nextValue);
222
+ (0, __WEBPACK_EXTERNAL_MODULE__flush_js_a3609ebe__.scheduleFlush)();
223
+ },
224
+ setScopeId (el, id) {
225
+ (0, __WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.pushOp)(__WEBPACK_EXTERNAL_MODULE__ops_js_e08da98b__.OP.SET_SCOPE_ID, el.id, (0, __WEBPACK_EXTERNAL_MODULE__scope_bridge_js_bd9512e9__.scopeIdToCssId)(id));
168
226
  (0, __WEBPACK_EXTERNAL_MODULE__flush_js_a3609ebe__.scheduleFlush)();
169
227
  },
170
228
  parentNode (node) {
@@ -172,9 +230,16 @@ const nodeOps = {
172
230
  },
173
231
  nextSibling (node) {
174
232
  return node.next;
233
+ },
234
+ querySelector (selector) {
235
+ if (selector.startsWith('#')) return idRegistry.get(selector.slice(1)) ?? null;
236
+ if (__DEV__) console.warn(`[vue-lynx] querySelector only supports #id selectors, got "${selector}".`);
237
+ return null;
175
238
  }
176
239
  };
177
240
  function resetNodeOpsState() {
178
241
  elementEventSigns.clear();
242
+ onceWrappers.clear();
243
+ idRegistry.clear();
179
244
  }
180
245
  export { nodeOps, resetNodeOpsState, resolveClass };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Convert a Vue scope ID (data-v-xxxxx) to a Lynx cssId (numeric).
3
+ * Vue uses 8-char hex hash strings. Lynx engine uses int32 for cssId,
4
+ * so we mask to 0x7fffffff to stay within the positive int32 range.
5
+ */
6
+ export declare function scopeIdToCssId(scopeId: string): number;
@@ -0,0 +1,5 @@
1
+ function scopeIdToCssId(scopeId) {
2
+ const hex = scopeId.replace(/^data-v-/, '');
3
+ return 0x7fffffff & Number.parseInt(hex, 16);
4
+ }
5
+ export { scopeIdToCssId };
@@ -23,6 +23,7 @@ export declare class ShadowElement {
23
23
  _vModelValue: string | undefined;
24
24
  _vModelHandler: ((data: unknown) => void) | undefined;
25
25
  _vModelEventProp: string | undefined;
26
+ _id: string | undefined;
26
27
  constructor(type: string, forceId?: number);
27
28
  /** CSS attribute selector that uniquely identifies this element on MT. */
28
29
  get _selector(): string;
@@ -14,6 +14,7 @@ class ShadowElement {
14
14
  _vModelValue = void 0;
15
15
  _vModelHandler = void 0;
16
16
  _vModelEventProp = void 0;
17
+ _id = void 0;
17
18
  constructor(type, forceId){
18
19
  if (void 0 === forceId) this.id = ShadowElement.nextId++;
19
20
  else this.id = forceId;
@@ -0,0 +1,62 @@
1
+ import type { DefineComponent } from 'vue';
2
+ import type { IntrinsicElements } from '@lynx-js/types';
3
+ type ExtractBindAsOn<T> = {
4
+ [P in keyof T as P extends `bind${infer Rest}` ? `on${Capitalize<Rest>}` : never]: T[P];
5
+ };
6
+ type NonBindProps<T> = Omit<T, `bind${string}` | 'className' | `main-thread:${string}` | `global-bind:${string}` | `global-catch:${string}`>;
7
+ /**
8
+ * Vue-compatible class binding type.
9
+ * @see https://vuejs.org/guide/essentials/class-and-style
10
+ */
11
+ type VueClassBinding = string | Record<string, unknown> | (VueClassBinding | false | null | undefined)[];
12
+ type MainThreadRefLike = {
13
+ readonly _wvid: number;
14
+ toJSON(): unknown;
15
+ };
16
+ type LynxEventHandler = ((...args: never[]) => unknown) | undefined;
17
+ type StringKeyOf<T> = Extract<keyof T, string>;
18
+ type Camelize<S extends string> = S extends `${infer Head}-${infer Tail}` ? `${Head}${Capitalize<Camelize<Tail>>}` : S;
19
+ type BindEventSuffix<T> = Extract<StringKeyOf<T>, `bind${string}`> extends `bind${infer S}` ? S : never;
20
+ type CatchEventSuffix<T> = Extract<StringKeyOf<T>, `catch${string}`> extends `catch${infer S}` ? S : never;
21
+ type PropValue<T, K extends string> = K extends keyof T ? T[K] : LynxEventHandler;
22
+ type LynxGlobalEventSourceProps<T> = {
23
+ [K in BindEventSuffix<T> as `global-bind${K}`]?: PropValue<T, `bind${K}`>;
24
+ } & {
25
+ [K in CatchEventSuffix<T> as `global-catch${K}`]?: PropValue<T, `catch${K}`>;
26
+ };
27
+ type LynxGlobalEventCamelProps<T> = {
28
+ [K in keyof LynxGlobalEventSourceProps<T> & string as Camelize<K>]?: LynxGlobalEventSourceProps<T>[K];
29
+ };
30
+ type LynxMainThreadEventKey<T> = Extract<StringKeyOf<T>, `bind${string}` | `catch${string}` | `global-bind${string}`> | keyof LynxGlobalEventSourceProps<T> & string;
31
+ type LynxMainThreadEventProps<T> = {
32
+ [K in LynxMainThreadEventKey<T> as `main-thread-${K}`]?: unknown;
33
+ } & {
34
+ [K in LynxMainThreadEventKey<T> as Camelize<`main-thread-${K}`>]?: unknown;
35
+ };
36
+ type LynxSpecialProps<T> = {
37
+ 'main-thread-ref'?: MainThreadRefLike | null;
38
+ mainThreadRef?: MainThreadRefLike | null;
39
+ } & LynxGlobalEventSourceProps<T> & LynxGlobalEventCamelProps<T> & LynxMainThreadEventProps<T>;
40
+ /**
41
+ * Maps Lynx intrinsic element props to Vue-friendly props:
42
+ *
43
+ * - Converts `bindXxx` props to Vue-style `onXxx` event handlers.
44
+ * - Removes the React-style `className` alias (Lynx carries both; Vue only
45
+ * needs `class`).
46
+ * - Widens `class` from `string` to the full {@link VueClassBinding} union so
47
+ * that array-syntax and object-syntax `:class` bindings pass TypeScript
48
+ * without errors.
49
+ * - Adds Vue Lynx special props for global events and main-thread worklets.
50
+ */
51
+ export type VueLynxProps<T> = ExtractBindAsOn<T> & Omit<NonBindProps<T>, 'class'> & {
52
+ class?: VueClassBinding;
53
+ } & LynxSpecialProps<T>;
54
+ type VueLynxComponent<T> = DefineComponent<VueLynxProps<T>>;
55
+ export type VueLynxElements = {
56
+ [K in keyof IntrinsicElements]: VueLynxComponent<IntrinsicElements[K]>;
57
+ };
58
+ declare module "vue" {
59
+ interface GlobalComponents extends VueLynxElements {
60
+ }
61
+ }
62
+ export {};
@@ -0,0 +1 @@
1
+ export * from './elements/index.js';
File without changes
@@ -0,0 +1,72 @@
1
+ const metaTags = [
2
+ 'block',
3
+ 'template',
4
+ 'slot'
5
+ ];
6
+ const lynxTags = [
7
+ 'component',
8
+ 'filter-image',
9
+ 'image',
10
+ 'inline-image',
11
+ 'inline-text',
12
+ 'inline-truncation',
13
+ 'list',
14
+ 'list-item',
15
+ 'list-row',
16
+ 'page',
17
+ 'scroll-view',
18
+ 'text',
19
+ 'view',
20
+ 'raw-text',
21
+ 'input',
22
+ 'textarea',
23
+ 'frame',
24
+ 'overlay',
25
+ 'svg'
26
+ ];
27
+ const nativeTags = metaTags;
28
+ const ELEMENT_NODE = 1;
29
+ const DIRECTIVE_NODE = 7;
30
+ const UNSUPPORTED_MODIFIERS = [
31
+ 'capture',
32
+ 'passive'
33
+ ];
34
+ function lynxModifierTransform(node, context) {
35
+ if (node.type !== ELEMENT_NODE) return;
36
+ for (const prop of node.props)if (prop.type === DIRECTIVE_NODE && 'on' === prop.name) for (const modifier of prop.modifiers){
37
+ const name = 'string' == typeof modifier ? modifier : modifier.content;
38
+ if (!UNSUPPORTED_MODIFIERS.includes(name)) continue;
39
+ const loc = 'object' == typeof modifier && modifier.loc ? modifier.loc : prop.loc;
40
+ const err = new SyntaxError(`Lynx does not support the .${name} event modifier.`);
41
+ err.code = 1001;
42
+ err.loc = loc;
43
+ context.onError(err);
44
+ }
45
+ }
46
+ const plugins = [
47
+ ({ vueCompilerOptions })=>{
48
+ vueCompilerOptions.nativeTags = nativeTags;
49
+ return {
50
+ version: 1
51
+ };
52
+ },
53
+ ({ vueCompilerOptions })=>{
54
+ vueCompilerOptions.nativeTags = nativeTags;
55
+ return {
56
+ version: 2
57
+ };
58
+ },
59
+ ()=>({
60
+ version: 2,
61
+ resolveTemplateCompilerOptions (options) {
62
+ options.isNativeTag = (tag)=>nativeTags.includes(tag);
63
+ options.nodeTransforms = [
64
+ ...options.nodeTransforms ?? [],
65
+ lynxModifierTransform
66
+ ];
67
+ return options;
68
+ }
69
+ })
70
+ ];
71
+ plugins.lynxTags = lynxTags;
72
+ module.exports = plugins;