svelte-origin 1.0.0-next.15 → 1.0.0-next.17

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/cli.js CHANGED
@@ -1919,7 +1919,7 @@ function parseObjectMembers(source) {
1919
1919
  }
1920
1920
 
1921
1921
  // src/transform/origin-transform.ts
1922
- function transformOriginCalls(s, source, neededImports) {
1922
+ function transformOriginCalls(s, source, neededImports, svelteImports) {
1923
1923
  const regex = /\$origin\s*\(/g;
1924
1924
  let match;
1925
1925
  let changed = false;
@@ -1935,14 +1935,14 @@ function transformOriginCalls(s, source, neededImports) {
1935
1935
  continue;
1936
1936
  }
1937
1937
  const definitionContent = source.slice(openParenIndex + 1, closeParenIndex);
1938
- const transformed = transformOriginDefinition(definitionContent);
1938
+ const transformed = transformOriginDefinition(definitionContent, svelteImports);
1939
1939
  s.overwrite(startIndex, closeParenIndex + 1, `__createOrigin(${transformed})`);
1940
1940
  neededImports.add("__createOrigin");
1941
1941
  changed = true;
1942
1942
  }
1943
1943
  return changed;
1944
1944
  }
1945
- function transformOriginDefinition(content) {
1945
+ function transformOriginDefinition(content, svelteImports) {
1946
1946
  let parents = [];
1947
1947
  let bodyContent = content.trim();
1948
1948
  let initCallback = null;
@@ -2007,7 +2007,7 @@ function transformOriginDefinition(content) {
2007
2007
  }
2008
2008
  }
2009
2009
  const attrDetails = parseAttrsSource(attrsContent);
2010
- const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName);
2010
+ const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName, svelteImports);
2011
2011
  const parentsCode = parents.length > 0 ? `[${parents.join(", ")}]` : "undefined";
2012
2012
  let configCode = `{
2013
2013
  __attrSchema: ${attrSchemaCode},
@@ -2027,22 +2027,48 @@ ${createFnBody}
2027
2027
  }`;
2028
2028
  return configCode;
2029
2029
  }
2030
- function transformOriginBody(content, parents = [], attrDetails = [], propName = "props") {
2030
+ function transformOriginBody(content, parents = [], attrDetails = [], propName = "props", _svelteImports) {
2031
2031
  let body = content.trim();
2032
2032
  const hasParents = parents.length > 0;
2033
- const attrGettersSetters = [];
2034
- for (const attr of attrDetails) {
2035
- if (attr.hasDefault) {
2036
- attrGettersSetters.push(`get ${attr.key}() { return __inputAttrs.${attr.key} ?? ${attr.defaultValue} }`);
2037
- } else {
2038
- attrGettersSetters.push(`get ${attr.key}() { return __inputAttrs.${attr.key} }`);
2033
+ const propsLines = [];
2034
+ if (attrDetails.length > 0) {
2035
+ const initialProps = [];
2036
+ for (const attr of attrDetails) {
2037
+ const defaultExpr = attr.hasDefault ? ` ?? ${attr.defaultValue}` : "";
2038
+ initialProps.push(`${attr.key}: __inputAttrs.${attr.key}${defaultExpr}`);
2039
+ }
2040
+ propsLines.push(`let __props = $state({ ${initialProps.join(", ")} })`);
2041
+ for (const attr of attrDetails) {
2042
+ const defaultExpr = attr.hasDefault ? ` ?? ${attr.defaultValue}` : "";
2043
+ const parentLast = `__last_parent_${attr.key}`;
2044
+ const localLast = `__last_local_${attr.key}`;
2045
+ propsLines.push(`let ${parentLast} = __inputAttrs.${attr.key}`, `let ${localLast} = __props.${attr.key}`, `$effect(() => {
2046
+ ` + ` const __parent = __inputAttrs.${attr.key}
2047
+ ` + ` const __local = __props.${attr.key}
2048
+
2049
+ ` + ` // Parent -> local
2050
+ ` + ` if (__parent !== ${parentLast}) {
2051
+ ` + ` ${parentLast} = __parent
2052
+ ` + ` if (__local !== __parent) {
2053
+ ` + ` __props.${attr.key} = __parent${defaultExpr}
2054
+ ` + ` }
2055
+ ` + ` ${localLast} = __props.${attr.key}
2056
+ ` + ` return
2057
+ ` + ` }
2058
+
2059
+ ` + ` // Local -> parent
2060
+ ` + ` if (__local !== ${localLast}) {
2061
+ ` + ` ${localLast} = __local
2062
+ ` + (attr.bindable ? ` try { __inputAttrs.${attr.key} = __local } catch {}
2063
+ ${parentLast} = __inputAttrs.${attr.key}
2064
+ ` : "") + ` }
2065
+ ` + `})`);
2039
2066
  }
2040
- attrGettersSetters.push(`set ${attr.key}(v) { __inputAttrs.${attr.key} = v }`);
2067
+ } else {
2068
+ propsLines.push("const __props = __inputAttrs");
2041
2069
  }
2042
- const propsObjectCode = attrGettersSetters.length > 0 ? ` const __props = {
2043
- ${attrGettersSetters.join(`,
2044
- `)}
2045
- }` : ` const __props = __inputAttrs`;
2070
+ const propsObjectCode = "\t\t" + propsLines.join(`
2071
+ `);
2046
2072
  if (!body) {
2047
2073
  const baseMembers = [`get ${propName}() { return __props }`];
2048
2074
  if (hasParents)
@@ -2728,9 +2754,10 @@ function transformScript(source, options = {}) {
2728
2754
  const { isComponent = false } = options;
2729
2755
  let changed = false;
2730
2756
  const neededImports = new Set;
2757
+ const svelteImports = new Set;
2731
2758
  let propsTypeDeclaration = null;
2732
2759
  if (!isComponent) {
2733
- changed = transformOriginCalls(s, source, neededImports) || changed;
2760
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2734
2761
  changed = transformStandaloneAttrsCalls(s, source, neededImports) || changed;
2735
2762
  }
2736
2763
  if (isComponent) {
@@ -2769,10 +2796,17 @@ function transformScript(source, options = {}) {
2769
2796
  `);
2770
2797
  }
2771
2798
  }
2772
- } else if (neededImports.size > 0) {
2773
- const importStatement = generateRuntimeImport([...neededImports]);
2774
- s.prepend(importStatement + `
2799
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
2800
+ if (neededImports.size > 0) {
2801
+ const importStatement = generateRuntimeImport([...neededImports]);
2802
+ s.prepend(importStatement + `
2803
+ `);
2804
+ }
2805
+ if (svelteImports.size > 0) {
2806
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2807
+ s.prepend(svelteImportStatement + `
2775
2808
  `);
2809
+ }
2776
2810
  }
2777
2811
  if (!changed) {
2778
2812
  return { code: source, changed: false };
@@ -2791,9 +2825,10 @@ async function transformScriptAsync(source, options) {
2791
2825
  const { isComponent = false, schemaResolver } = options;
2792
2826
  let changed = false;
2793
2827
  const neededImports = new Set;
2828
+ const svelteImports = new Set;
2794
2829
  let propsTypeDeclaration = null;
2795
2830
  if (!isComponent) {
2796
- changed = transformOriginCalls(s, source, neededImports) || changed;
2831
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2797
2832
  changed = transformStandaloneAttrsCalls(s, source, neededImports) || changed;
2798
2833
  }
2799
2834
  if (isComponent) {
@@ -2832,10 +2867,17 @@ async function transformScriptAsync(source, options) {
2832
2867
  `);
2833
2868
  }
2834
2869
  }
2835
- } else if (neededImports.size > 0) {
2836
- const importStatement = generateRuntimeImport([...neededImports]);
2837
- s.prepend(importStatement + `
2870
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
2871
+ if (neededImports.size > 0) {
2872
+ const importStatement = generateRuntimeImport([...neededImports]);
2873
+ s.prepend(importStatement + `
2874
+ `);
2875
+ }
2876
+ if (svelteImports.size > 0) {
2877
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2878
+ s.prepend(svelteImportStatement + `
2838
2879
  `);
2880
+ }
2839
2881
  }
2840
2882
  if (!changed) {
2841
2883
  return { code: source, changed: false };
@@ -2854,9 +2896,10 @@ async function transformScriptContent(source, options) {
2854
2896
  const { isComponent = false, schemaResolver } = options;
2855
2897
  let changed = false;
2856
2898
  const neededImports = new Set;
2899
+ const svelteImports = new Set;
2857
2900
  let propsTypeDeclaration = null;
2858
2901
  if (!isComponent) {
2859
- changed = transformOriginCalls(s, source, neededImports) || changed;
2902
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2860
2903
  }
2861
2904
  if (isComponent) {
2862
2905
  const result = await transformAttrsOriginCalls(s, source, neededImports, schemaResolver);
@@ -2869,11 +2912,22 @@ async function transformScriptContent(source, options) {
2869
2912
  if (neededImports.size > 0) {
2870
2913
  const importStatement = generateRuntimeImport([...neededImports]);
2871
2914
  s.prepend(importStatement + `
2915
+ `);
2916
+ }
2917
+ if (svelteImports.size > 0) {
2918
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2919
+ s.prepend(svelteImportStatement + `
2872
2920
  `);
2873
2921
  }
2874
2922
  if (propsTypeDeclaration) {
2875
2923
  const afterImports = findPropsInjectionPosition(source);
2876
- const offset = neededImports.size > 0 ? generateRuntimeImport([...neededImports]).length + 1 : 0;
2924
+ let offset = 0;
2925
+ if (neededImports.size > 0) {
2926
+ offset += generateRuntimeImport([...neededImports]).length + 1;
2927
+ }
2928
+ if (svelteImports.size > 0) {
2929
+ offset += `import { ${[...svelteImports].join(", ")} } from 'svelte'`.length + 1;
2930
+ }
2877
2931
  s.appendLeft(afterImports + offset, propsTypeDeclaration + `
2878
2932
  `);
2879
2933
  }
package/dist/index.js CHANGED
@@ -3475,24 +3475,39 @@ function __attrsFor(factory, rawAttrs) {
3475
3475
  const wrapper = {};
3476
3476
  const localValues = {};
3477
3477
  const hasLocalValue = {};
3478
- for (const key2 of Object.keys(schema)) {
3479
- Object.defineProperty(wrapper, key2, {
3478
+ const defineExposedProp = (key2, info) => {
3479
+ if (Object.prototype.hasOwnProperty.call(wrapper, key2))
3480
+ return;
3481
+ const base = {
3480
3482
  get() {
3481
- if (hasLocalValue[key2]) {
3483
+ if (hasLocalValue[key2])
3482
3484
  return localValues[key2];
3483
- }
3484
3485
  return rawAttrs[key2];
3485
3486
  },
3486
- set(value) {
3487
- localValues[key2] = value;
3488
- hasLocalValue[key2] = true;
3489
- try {
3490
- rawAttrs[key2] = value;
3491
- } catch {}
3492
- },
3493
3487
  enumerable: true,
3494
3488
  configurable: true
3495
- });
3489
+ };
3490
+ if (info.bindable) {
3491
+ Object.defineProperty(wrapper, key2, {
3492
+ ...base,
3493
+ set(value) {
3494
+ localValues[key2] = value;
3495
+ hasLocalValue[key2] = true;
3496
+ try {
3497
+ rawAttrs[key2] = value;
3498
+ } catch {}
3499
+ }
3500
+ });
3501
+ } else {
3502
+ Object.defineProperty(wrapper, key2, base);
3503
+ }
3504
+ };
3505
+ for (const [key2, info] of Object.entries(schema)) {
3506
+ const parentValue = rawAttrs[key2];
3507
+ const shouldExpose = !info.bindable || !info.hasDefault || parentValue !== undefined;
3508
+ if (shouldExpose) {
3509
+ defineExposedProp(key2, info);
3510
+ }
3496
3511
  }
3497
3512
  for (const sym of Object.getOwnPropertySymbols(rawAttrs)) {
3498
3513
  Object.defineProperty(wrapper, sym, {
@@ -3505,34 +3520,57 @@ function __attrsFor(factory, rawAttrs) {
3505
3520
  }
3506
3521
  return new Proxy(wrapper, {
3507
3522
  get(target, prop2) {
3508
- if (prop2 in target) {
3509
- return target[prop2];
3523
+ if (typeof prop2 === "string" && prop2 in schema) {
3524
+ if (hasLocalValue[prop2])
3525
+ return localValues[prop2];
3526
+ return rawAttrs[prop2];
3510
3527
  }
3528
+ if (prop2 in target)
3529
+ return target[prop2];
3511
3530
  return rawAttrs[prop2];
3512
3531
  },
3513
3532
  set(target, prop2, value) {
3533
+ if (typeof prop2 === "string" && prop2 in schema) {
3534
+ localValues[prop2] = value;
3535
+ hasLocalValue[prop2] = true;
3536
+ if (!Object.prototype.hasOwnProperty.call(wrapper, prop2)) {
3537
+ defineExposedProp(prop2, schema[prop2]);
3538
+ }
3539
+ if (schema[prop2].bindable) {
3540
+ try {
3541
+ rawAttrs[prop2] = value;
3542
+ } catch {}
3543
+ }
3544
+ return true;
3545
+ }
3514
3546
  if (prop2 in target) {
3515
- target[prop2] = value;
3547
+ try {
3548
+ target[prop2] = value;
3549
+ } catch {}
3516
3550
  return true;
3517
3551
  }
3518
3552
  try {
3519
3553
  rawAttrs[prop2] = value;
3520
3554
  } catch {
3521
- localValues[prop2] = value;
3522
- hasLocalValue[prop2] = true;
3555
+ if (typeof prop2 === "string") {
3556
+ localValues[prop2] = value;
3557
+ hasLocalValue[prop2] = true;
3558
+ }
3523
3559
  }
3524
3560
  return true;
3525
3561
  },
3526
3562
  has(target, prop2) {
3563
+ if (typeof prop2 === "string" && prop2 in schema) {
3564
+ return prop2 in target || hasLocalValue[prop2];
3565
+ }
3527
3566
  return prop2 in target || prop2 in rawAttrs;
3528
3567
  },
3529
3568
  ownKeys() {
3530
3569
  return [...Object.keys(wrapper), ...Object.getOwnPropertySymbols(rawAttrs)];
3531
3570
  },
3532
3571
  getOwnPropertyDescriptor(target, prop2) {
3533
- if (prop2 in target) {
3572
+ if (prop2 in target)
3534
3573
  return Object.getOwnPropertyDescriptor(target, prop2);
3535
- }
3536
3574
  return Object.getOwnPropertyDescriptor(rawAttrs, prop2);
3537
3575
  }
3538
3576
  });
@@ -5969,7 +6007,7 @@ function parseObjectMembers(source2) {
5969
6007
  }
5970
6008
 
5971
6009
  // src/transform/origin-transform.ts
5972
- function transformOriginCalls(s, source2, neededImports) {
6010
+ function transformOriginCalls(s, source2, neededImports, svelteImports) {
5973
6011
  const regex = /\$origin\s*\(/g;
5974
6012
  let match;
5975
6013
  let changed = false;
@@ -5985,14 +6023,14 @@ function transformOriginCalls(s, source2, neededImports) {
5985
6023
  continue;
5986
6024
  }
5987
6025
  const definitionContent = source2.slice(openParenIndex + 1, closeParenIndex);
5988
- const transformed = transformOriginDefinition(definitionContent);
6026
+ const transformed = transformOriginDefinition(definitionContent, svelteImports);
5989
6027
  s.overwrite(startIndex, closeParenIndex + 1, `__createOrigin(${transformed})`);
5990
6028
  neededImports.add("__createOrigin");
5991
6029
  changed = true;
5992
6030
  }
5993
6031
  return changed;
5994
6032
  }
5995
- function transformOriginDefinition(content) {
6033
+ function transformOriginDefinition(content, svelteImports) {
5996
6034
  let parents = [];
5997
6035
  let bodyContent = content.trim();
5998
6036
  let initCallback = null;
@@ -6057,7 +6095,7 @@ function transformOriginDefinition(content) {
6057
6095
  }
6058
6096
  }
6059
6097
  const attrDetails = parseAttrsSource(attrsContent);
6060
- const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName);
6098
+ const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName, svelteImports);
6061
6099
  const parentsCode = parents.length > 0 ? `[${parents.join(", ")}]` : "undefined";
6062
6100
  let configCode = `{
6063
6101
  __attrSchema: ${attrSchemaCode},
@@ -6077,22 +6115,48 @@ ${createFnBody}
6077
6115
  }`;
6078
6116
  return configCode;
6079
6117
  }
6080
- function transformOriginBody(content, parents = [], attrDetails = [], propName = "props") {
6118
+ function transformOriginBody(content, parents = [], attrDetails = [], propName = "props", _svelteImports) {
6081
6119
  let body = content.trim();
6082
6120
  const hasParents = parents.length > 0;
6083
- const attrGettersSetters = [];
6084
- for (const attr2 of attrDetails) {
6085
- if (attr2.hasDefault) {
6086
- attrGettersSetters.push(`get ${attr2.key}() { return __inputAttrs.${attr2.key} ?? ${attr2.defaultValue} }`);
6087
- } else {
6088
- attrGettersSetters.push(`get ${attr2.key}() { return __inputAttrs.${attr2.key} }`);
6121
+ const propsLines = [];
6122
+ if (attrDetails.length > 0) {
6123
+ const initialProps = [];
6124
+ for (const attr2 of attrDetails) {
6125
+ const defaultExpr = attr2.hasDefault ? ` ?? ${attr2.defaultValue}` : "";
6126
+ initialProps.push(`${attr2.key}: __inputAttrs.${attr2.key}${defaultExpr}`);
6127
+ }
6128
+ propsLines.push(`let __props = $state({ ${initialProps.join(", ")} })`);
6129
+ for (const attr2 of attrDetails) {
6130
+ const defaultExpr = attr2.hasDefault ? ` ?? ${attr2.defaultValue}` : "";
6131
+ const parentLast = `__last_parent_${attr2.key}`;
6132
+ const localLast = `__last_local_${attr2.key}`;
6133
+ propsLines.push(`let ${parentLast} = __inputAttrs.${attr2.key}`, `let ${localLast} = __props.${attr2.key}`, `$effect(() => {
6134
+ ` + ` const __parent = __inputAttrs.${attr2.key}
6135
+ ` + ` const __local = __props.${attr2.key}
6136
+
6137
+ ` + ` // Parent -> local
6138
+ ` + ` if (__parent !== ${parentLast}) {
6139
+ ` + ` ${parentLast} = __parent
6140
+ ` + ` if (__local !== __parent) {
6141
+ ` + ` __props.${attr2.key} = __parent${defaultExpr}
6142
+ ` + ` }
6143
+ ` + ` ${localLast} = __props.${attr2.key}
6144
+ ` + ` return
6145
+ ` + ` }
6146
+
6147
+ ` + ` // Local -> parent
6148
+ ` + ` if (__local !== ${localLast}) {
6149
+ ` + ` ${localLast} = __local
6150
+ ` + (attr2.bindable ? ` try { __inputAttrs.${attr2.key} = __local } catch {}
6151
+ ${parentLast} = __inputAttrs.${attr2.key}
6152
+ ` : "") + ` }
6153
+ ` + `})`);
6089
6154
  }
6090
- attrGettersSetters.push(`set ${attr2.key}(v) { __inputAttrs.${attr2.key} = v }`);
6155
+ } else {
6156
+ propsLines.push("const __props = __inputAttrs");
6091
6157
  }
6092
- const propsObjectCode = attrGettersSetters.length > 0 ? ` const __props = {
6093
- ${attrGettersSetters.join(`,
6094
- `)}
6095
- }` : ` const __props = __inputAttrs`;
6158
+ const propsObjectCode = "\t\t" + propsLines.join(`
6159
+ `);
6096
6160
  if (!body) {
6097
6161
  const baseMembers = [`get ${propName}() { return __props }`];
6098
6162
  if (hasParents)
@@ -6509,9 +6573,10 @@ function transformScript(source2, options = {}) {
6509
6573
  const { isComponent = false } = options;
6510
6574
  let changed = false;
6511
6575
  const neededImports = new Set;
6576
+ const svelteImports = new Set;
6512
6577
  let propsTypeDeclaration = null;
6513
6578
  if (!isComponent) {
6514
- changed = transformOriginCalls(s, source2, neededImports) || changed;
6579
+ changed = transformOriginCalls(s, source2, neededImports, svelteImports) || changed;
6515
6580
  changed = transformStandaloneAttrsCalls(s, source2, neededImports) || changed;
6516
6581
  }
6517
6582
  if (isComponent) {
@@ -6550,10 +6615,17 @@ function transformScript(source2, options = {}) {
6550
6615
  `);
6551
6616
  }
6552
6617
  }
6553
- } else if (neededImports.size > 0) {
6554
- const importStatement = generateRuntimeImport([...neededImports]);
6555
- s.prepend(importStatement + `
6618
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
6619
+ if (neededImports.size > 0) {
6620
+ const importStatement = generateRuntimeImport([...neededImports]);
6621
+ s.prepend(importStatement + `
6622
+ `);
6623
+ }
6624
+ if (svelteImports.size > 0) {
6625
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
6626
+ s.prepend(svelteImportStatement + `
6556
6627
  `);
6628
+ }
6557
6629
  }
6558
6630
  if (!changed) {
6559
6631
  return { code: source2, changed: false };
@@ -6572,9 +6644,10 @@ async function transformScriptAsync(source2, options) {
6572
6644
  const { isComponent = false, schemaResolver } = options;
6573
6645
  let changed = false;
6574
6646
  const neededImports = new Set;
6647
+ const svelteImports = new Set;
6575
6648
  let propsTypeDeclaration = null;
6576
6649
  if (!isComponent) {
6577
- changed = transformOriginCalls(s, source2, neededImports) || changed;
6650
+ changed = transformOriginCalls(s, source2, neededImports, svelteImports) || changed;
6578
6651
  changed = transformStandaloneAttrsCalls(s, source2, neededImports) || changed;
6579
6652
  }
6580
6653
  if (isComponent) {
@@ -6613,10 +6686,17 @@ async function transformScriptAsync(source2, options) {
6613
6686
  `);
6614
6687
  }
6615
6688
  }
6616
- } else if (neededImports.size > 0) {
6617
- const importStatement = generateRuntimeImport([...neededImports]);
6618
- s.prepend(importStatement + `
6689
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
6690
+ if (neededImports.size > 0) {
6691
+ const importStatement = generateRuntimeImport([...neededImports]);
6692
+ s.prepend(importStatement + `
6619
6693
  `);
6694
+ }
6695
+ if (svelteImports.size > 0) {
6696
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
6697
+ s.prepend(svelteImportStatement + `
6698
+ `);
6699
+ }
6620
6700
  }
6621
6701
  if (!changed) {
6622
6702
  return { code: source2, changed: false };
@@ -6635,9 +6715,10 @@ async function transformScriptContent(source2, options) {
6635
6715
  const { isComponent = false, schemaResolver } = options;
6636
6716
  let changed = false;
6637
6717
  const neededImports = new Set;
6718
+ const svelteImports = new Set;
6638
6719
  let propsTypeDeclaration = null;
6639
6720
  if (!isComponent) {
6640
- changed = transformOriginCalls(s, source2, neededImports) || changed;
6721
+ changed = transformOriginCalls(s, source2, neededImports, svelteImports) || changed;
6641
6722
  }
6642
6723
  if (isComponent) {
6643
6724
  const result = await transformAttrsOriginCalls(s, source2, neededImports, schemaResolver);
@@ -6650,11 +6731,22 @@ async function transformScriptContent(source2, options) {
6650
6731
  if (neededImports.size > 0) {
6651
6732
  const importStatement = generateRuntimeImport([...neededImports]);
6652
6733
  s.prepend(importStatement + `
6734
+ `);
6735
+ }
6736
+ if (svelteImports.size > 0) {
6737
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
6738
+ s.prepend(svelteImportStatement + `
6653
6739
  `);
6654
6740
  }
6655
6741
  if (propsTypeDeclaration) {
6656
6742
  const afterImports = findPropsInjectionPosition(source2);
6657
- const offset = neededImports.size > 0 ? generateRuntimeImport([...neededImports]).length + 1 : 0;
6743
+ let offset = 0;
6744
+ if (neededImports.size > 0) {
6745
+ offset += generateRuntimeImport([...neededImports]).length + 1;
6746
+ }
6747
+ if (svelteImports.size > 0) {
6748
+ offset += `import { ${[...svelteImports].join(", ")} } from 'svelte'`.length + 1;
6749
+ }
6658
6750
  s.appendLeft(afterImports + offset, propsTypeDeclaration + `
6659
6751
  `);
6660
6752
  }
package/dist/plugin.js CHANGED
@@ -1913,7 +1913,7 @@ function parseObjectMembers(source) {
1913
1913
  }
1914
1914
 
1915
1915
  // src/transform/origin-transform.ts
1916
- function transformOriginCalls(s, source, neededImports) {
1916
+ function transformOriginCalls(s, source, neededImports, svelteImports) {
1917
1917
  const regex = /\$origin\s*\(/g;
1918
1918
  let match;
1919
1919
  let changed = false;
@@ -1929,14 +1929,14 @@ function transformOriginCalls(s, source, neededImports) {
1929
1929
  continue;
1930
1930
  }
1931
1931
  const definitionContent = source.slice(openParenIndex + 1, closeParenIndex);
1932
- const transformed = transformOriginDefinition(definitionContent);
1932
+ const transformed = transformOriginDefinition(definitionContent, svelteImports);
1933
1933
  s.overwrite(startIndex, closeParenIndex + 1, `__createOrigin(${transformed})`);
1934
1934
  neededImports.add("__createOrigin");
1935
1935
  changed = true;
1936
1936
  }
1937
1937
  return changed;
1938
1938
  }
1939
- function transformOriginDefinition(content) {
1939
+ function transformOriginDefinition(content, svelteImports) {
1940
1940
  let parents = [];
1941
1941
  let bodyContent = content.trim();
1942
1942
  let initCallback = null;
@@ -2001,7 +2001,7 @@ function transformOriginDefinition(content) {
2001
2001
  }
2002
2002
  }
2003
2003
  const attrDetails = parseAttrsSource(attrsContent);
2004
- const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName);
2004
+ const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName, svelteImports);
2005
2005
  const parentsCode = parents.length > 0 ? `[${parents.join(", ")}]` : "undefined";
2006
2006
  let configCode = `{
2007
2007
  __attrSchema: ${attrSchemaCode},
@@ -2021,22 +2021,48 @@ ${createFnBody}
2021
2021
  }`;
2022
2022
  return configCode;
2023
2023
  }
2024
- function transformOriginBody(content, parents = [], attrDetails = [], propName = "props") {
2024
+ function transformOriginBody(content, parents = [], attrDetails = [], propName = "props", _svelteImports) {
2025
2025
  let body = content.trim();
2026
2026
  const hasParents = parents.length > 0;
2027
- const attrGettersSetters = [];
2028
- for (const attr of attrDetails) {
2029
- if (attr.hasDefault) {
2030
- attrGettersSetters.push(`get ${attr.key}() { return __inputAttrs.${attr.key} ?? ${attr.defaultValue} }`);
2031
- } else {
2032
- attrGettersSetters.push(`get ${attr.key}() { return __inputAttrs.${attr.key} }`);
2027
+ const propsLines = [];
2028
+ if (attrDetails.length > 0) {
2029
+ const initialProps = [];
2030
+ for (const attr of attrDetails) {
2031
+ const defaultExpr = attr.hasDefault ? ` ?? ${attr.defaultValue}` : "";
2032
+ initialProps.push(`${attr.key}: __inputAttrs.${attr.key}${defaultExpr}`);
2033
+ }
2034
+ propsLines.push(`let __props = $state({ ${initialProps.join(", ")} })`);
2035
+ for (const attr of attrDetails) {
2036
+ const defaultExpr = attr.hasDefault ? ` ?? ${attr.defaultValue}` : "";
2037
+ const parentLast = `__last_parent_${attr.key}`;
2038
+ const localLast = `__last_local_${attr.key}`;
2039
+ propsLines.push(`let ${parentLast} = __inputAttrs.${attr.key}`, `let ${localLast} = __props.${attr.key}`, `$effect(() => {
2040
+ ` + ` const __parent = __inputAttrs.${attr.key}
2041
+ ` + ` const __local = __props.${attr.key}
2042
+
2043
+ ` + ` // Parent -> local
2044
+ ` + ` if (__parent !== ${parentLast}) {
2045
+ ` + ` ${parentLast} = __parent
2046
+ ` + ` if (__local !== __parent) {
2047
+ ` + ` __props.${attr.key} = __parent${defaultExpr}
2048
+ ` + ` }
2049
+ ` + ` ${localLast} = __props.${attr.key}
2050
+ ` + ` return
2051
+ ` + ` }
2052
+
2053
+ ` + ` // Local -> parent
2054
+ ` + ` if (__local !== ${localLast}) {
2055
+ ` + ` ${localLast} = __local
2056
+ ` + (attr.bindable ? ` try { __inputAttrs.${attr.key} = __local } catch {}
2057
+ ${parentLast} = __inputAttrs.${attr.key}
2058
+ ` : "") + ` }
2059
+ ` + `})`);
2033
2060
  }
2034
- attrGettersSetters.push(`set ${attr.key}(v) { __inputAttrs.${attr.key} = v }`);
2061
+ } else {
2062
+ propsLines.push("const __props = __inputAttrs");
2035
2063
  }
2036
- const propsObjectCode = attrGettersSetters.length > 0 ? ` const __props = {
2037
- ${attrGettersSetters.join(`,
2038
- `)}
2039
- }` : ` const __props = __inputAttrs`;
2064
+ const propsObjectCode = "\t\t" + propsLines.join(`
2065
+ `);
2040
2066
  if (!body) {
2041
2067
  const baseMembers = [`get ${propName}() { return __props }`];
2042
2068
  if (hasParents)
@@ -2722,9 +2748,10 @@ function transformScript(source, options = {}) {
2722
2748
  const { isComponent = false } = options;
2723
2749
  let changed = false;
2724
2750
  const neededImports = new Set;
2751
+ const svelteImports = new Set;
2725
2752
  let propsTypeDeclaration = null;
2726
2753
  if (!isComponent) {
2727
- changed = transformOriginCalls(s, source, neededImports) || changed;
2754
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2728
2755
  changed = transformStandaloneAttrsCalls(s, source, neededImports) || changed;
2729
2756
  }
2730
2757
  if (isComponent) {
@@ -2763,10 +2790,17 @@ function transformScript(source, options = {}) {
2763
2790
  `);
2764
2791
  }
2765
2792
  }
2766
- } else if (neededImports.size > 0) {
2767
- const importStatement = generateRuntimeImport([...neededImports]);
2768
- s.prepend(importStatement + `
2793
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
2794
+ if (neededImports.size > 0) {
2795
+ const importStatement = generateRuntimeImport([...neededImports]);
2796
+ s.prepend(importStatement + `
2797
+ `);
2798
+ }
2799
+ if (svelteImports.size > 0) {
2800
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2801
+ s.prepend(svelteImportStatement + `
2769
2802
  `);
2803
+ }
2770
2804
  }
2771
2805
  if (!changed) {
2772
2806
  return { code: source, changed: false };
@@ -2785,9 +2819,10 @@ async function transformScriptAsync(source, options) {
2785
2819
  const { isComponent = false, schemaResolver } = options;
2786
2820
  let changed = false;
2787
2821
  const neededImports = new Set;
2822
+ const svelteImports = new Set;
2788
2823
  let propsTypeDeclaration = null;
2789
2824
  if (!isComponent) {
2790
- changed = transformOriginCalls(s, source, neededImports) || changed;
2825
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2791
2826
  changed = transformStandaloneAttrsCalls(s, source, neededImports) || changed;
2792
2827
  }
2793
2828
  if (isComponent) {
@@ -2826,10 +2861,17 @@ async function transformScriptAsync(source, options) {
2826
2861
  `);
2827
2862
  }
2828
2863
  }
2829
- } else if (neededImports.size > 0) {
2830
- const importStatement = generateRuntimeImport([...neededImports]);
2831
- s.prepend(importStatement + `
2864
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
2865
+ if (neededImports.size > 0) {
2866
+ const importStatement = generateRuntimeImport([...neededImports]);
2867
+ s.prepend(importStatement + `
2868
+ `);
2869
+ }
2870
+ if (svelteImports.size > 0) {
2871
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2872
+ s.prepend(svelteImportStatement + `
2832
2873
  `);
2874
+ }
2833
2875
  }
2834
2876
  if (!changed) {
2835
2877
  return { code: source, changed: false };
@@ -2848,9 +2890,10 @@ async function transformScriptContent(source, options) {
2848
2890
  const { isComponent = false, schemaResolver } = options;
2849
2891
  let changed = false;
2850
2892
  const neededImports = new Set;
2893
+ const svelteImports = new Set;
2851
2894
  let propsTypeDeclaration = null;
2852
2895
  if (!isComponent) {
2853
- changed = transformOriginCalls(s, source, neededImports) || changed;
2896
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2854
2897
  }
2855
2898
  if (isComponent) {
2856
2899
  const result = await transformAttrsOriginCalls(s, source, neededImports, schemaResolver);
@@ -2863,11 +2906,22 @@ async function transformScriptContent(source, options) {
2863
2906
  if (neededImports.size > 0) {
2864
2907
  const importStatement = generateRuntimeImport([...neededImports]);
2865
2908
  s.prepend(importStatement + `
2909
+ `);
2910
+ }
2911
+ if (svelteImports.size > 0) {
2912
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2913
+ s.prepend(svelteImportStatement + `
2866
2914
  `);
2867
2915
  }
2868
2916
  if (propsTypeDeclaration) {
2869
2917
  const afterImports = findPropsInjectionPosition(source);
2870
- const offset = neededImports.size > 0 ? generateRuntimeImport([...neededImports]).length + 1 : 0;
2918
+ let offset = 0;
2919
+ if (neededImports.size > 0) {
2920
+ offset += generateRuntimeImport([...neededImports]).length + 1;
2921
+ }
2922
+ if (svelteImports.size > 0) {
2923
+ offset += `import { ${[...svelteImports].join(", ")} } from 'svelte'`.length + 1;
2924
+ }
2871
2925
  s.appendLeft(afterImports + offset, propsTypeDeclaration + `
2872
2926
  `);
2873
2927
  }
@@ -1917,7 +1917,7 @@ function parseObjectMembers(source) {
1917
1917
  }
1918
1918
 
1919
1919
  // src/transform/origin-transform.ts
1920
- function transformOriginCalls(s, source, neededImports) {
1920
+ function transformOriginCalls(s, source, neededImports, svelteImports) {
1921
1921
  const regex = /\$origin\s*\(/g;
1922
1922
  let match;
1923
1923
  let changed = false;
@@ -1933,14 +1933,14 @@ function transformOriginCalls(s, source, neededImports) {
1933
1933
  continue;
1934
1934
  }
1935
1935
  const definitionContent = source.slice(openParenIndex + 1, closeParenIndex);
1936
- const transformed = transformOriginDefinition(definitionContent);
1936
+ const transformed = transformOriginDefinition(definitionContent, svelteImports);
1937
1937
  s.overwrite(startIndex, closeParenIndex + 1, `__createOrigin(${transformed})`);
1938
1938
  neededImports.add("__createOrigin");
1939
1939
  changed = true;
1940
1940
  }
1941
1941
  return changed;
1942
1942
  }
1943
- function transformOriginDefinition(content) {
1943
+ function transformOriginDefinition(content, svelteImports) {
1944
1944
  let parents = [];
1945
1945
  let bodyContent = content.trim();
1946
1946
  let initCallback = null;
@@ -2005,7 +2005,7 @@ function transformOriginDefinition(content) {
2005
2005
  }
2006
2006
  }
2007
2007
  const attrDetails = parseAttrsSource(attrsContent);
2008
- const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName);
2008
+ const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName, svelteImports);
2009
2009
  const parentsCode = parents.length > 0 ? `[${parents.join(", ")}]` : "undefined";
2010
2010
  let configCode = `{
2011
2011
  __attrSchema: ${attrSchemaCode},
@@ -2025,22 +2025,48 @@ ${createFnBody}
2025
2025
  }`;
2026
2026
  return configCode;
2027
2027
  }
2028
- function transformOriginBody(content, parents = [], attrDetails = [], propName = "props") {
2028
+ function transformOriginBody(content, parents = [], attrDetails = [], propName = "props", _svelteImports) {
2029
2029
  let body = content.trim();
2030
2030
  const hasParents = parents.length > 0;
2031
- const attrGettersSetters = [];
2032
- for (const attr of attrDetails) {
2033
- if (attr.hasDefault) {
2034
- attrGettersSetters.push(`get ${attr.key}() { return __inputAttrs.${attr.key} ?? ${attr.defaultValue} }`);
2035
- } else {
2036
- attrGettersSetters.push(`get ${attr.key}() { return __inputAttrs.${attr.key} }`);
2031
+ const propsLines = [];
2032
+ if (attrDetails.length > 0) {
2033
+ const initialProps = [];
2034
+ for (const attr of attrDetails) {
2035
+ const defaultExpr = attr.hasDefault ? ` ?? ${attr.defaultValue}` : "";
2036
+ initialProps.push(`${attr.key}: __inputAttrs.${attr.key}${defaultExpr}`);
2037
+ }
2038
+ propsLines.push(`let __props = $state({ ${initialProps.join(", ")} })`);
2039
+ for (const attr of attrDetails) {
2040
+ const defaultExpr = attr.hasDefault ? ` ?? ${attr.defaultValue}` : "";
2041
+ const parentLast = `__last_parent_${attr.key}`;
2042
+ const localLast = `__last_local_${attr.key}`;
2043
+ propsLines.push(`let ${parentLast} = __inputAttrs.${attr.key}`, `let ${localLast} = __props.${attr.key}`, `$effect(() => {
2044
+ ` + ` const __parent = __inputAttrs.${attr.key}
2045
+ ` + ` const __local = __props.${attr.key}
2046
+
2047
+ ` + ` // Parent -> local
2048
+ ` + ` if (__parent !== ${parentLast}) {
2049
+ ` + ` ${parentLast} = __parent
2050
+ ` + ` if (__local !== __parent) {
2051
+ ` + ` __props.${attr.key} = __parent${defaultExpr}
2052
+ ` + ` }
2053
+ ` + ` ${localLast} = __props.${attr.key}
2054
+ ` + ` return
2055
+ ` + ` }
2056
+
2057
+ ` + ` // Local -> parent
2058
+ ` + ` if (__local !== ${localLast}) {
2059
+ ` + ` ${localLast} = __local
2060
+ ` + (attr.bindable ? ` try { __inputAttrs.${attr.key} = __local } catch {}
2061
+ ${parentLast} = __inputAttrs.${attr.key}
2062
+ ` : "") + ` }
2063
+ ` + `})`);
2037
2064
  }
2038
- attrGettersSetters.push(`set ${attr.key}(v) { __inputAttrs.${attr.key} = v }`);
2065
+ } else {
2066
+ propsLines.push("const __props = __inputAttrs");
2039
2067
  }
2040
- const propsObjectCode = attrGettersSetters.length > 0 ? ` const __props = {
2041
- ${attrGettersSetters.join(`,
2042
- `)}
2043
- }` : ` const __props = __inputAttrs`;
2068
+ const propsObjectCode = "\t\t" + propsLines.join(`
2069
+ `);
2044
2070
  if (!body) {
2045
2071
  const baseMembers = [`get ${propName}() { return __props }`];
2046
2072
  if (hasParents)
@@ -2726,9 +2752,10 @@ function transformScript(source, options = {}) {
2726
2752
  const { isComponent = false } = options;
2727
2753
  let changed = false;
2728
2754
  const neededImports = new Set;
2755
+ const svelteImports = new Set;
2729
2756
  let propsTypeDeclaration = null;
2730
2757
  if (!isComponent) {
2731
- changed = transformOriginCalls(s, source, neededImports) || changed;
2758
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2732
2759
  changed = transformStandaloneAttrsCalls(s, source, neededImports) || changed;
2733
2760
  }
2734
2761
  if (isComponent) {
@@ -2767,10 +2794,17 @@ function transformScript(source, options = {}) {
2767
2794
  `);
2768
2795
  }
2769
2796
  }
2770
- } else if (neededImports.size > 0) {
2771
- const importStatement = generateRuntimeImport([...neededImports]);
2772
- s.prepend(importStatement + `
2797
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
2798
+ if (neededImports.size > 0) {
2799
+ const importStatement = generateRuntimeImport([...neededImports]);
2800
+ s.prepend(importStatement + `
2801
+ `);
2802
+ }
2803
+ if (svelteImports.size > 0) {
2804
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2805
+ s.prepend(svelteImportStatement + `
2773
2806
  `);
2807
+ }
2774
2808
  }
2775
2809
  if (!changed) {
2776
2810
  return { code: source, changed: false };
@@ -2789,9 +2823,10 @@ async function transformScriptAsync(source, options) {
2789
2823
  const { isComponent = false, schemaResolver } = options;
2790
2824
  let changed = false;
2791
2825
  const neededImports = new Set;
2826
+ const svelteImports = new Set;
2792
2827
  let propsTypeDeclaration = null;
2793
2828
  if (!isComponent) {
2794
- changed = transformOriginCalls(s, source, neededImports) || changed;
2829
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2795
2830
  changed = transformStandaloneAttrsCalls(s, source, neededImports) || changed;
2796
2831
  }
2797
2832
  if (isComponent) {
@@ -2830,10 +2865,17 @@ async function transformScriptAsync(source, options) {
2830
2865
  `);
2831
2866
  }
2832
2867
  }
2833
- } else if (neededImports.size > 0) {
2834
- const importStatement = generateRuntimeImport([...neededImports]);
2835
- s.prepend(importStatement + `
2868
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
2869
+ if (neededImports.size > 0) {
2870
+ const importStatement = generateRuntimeImport([...neededImports]);
2871
+ s.prepend(importStatement + `
2872
+ `);
2873
+ }
2874
+ if (svelteImports.size > 0) {
2875
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2876
+ s.prepend(svelteImportStatement + `
2836
2877
  `);
2878
+ }
2837
2879
  }
2838
2880
  if (!changed) {
2839
2881
  return { code: source, changed: false };
@@ -2852,9 +2894,10 @@ async function transformScriptContent(source, options) {
2852
2894
  const { isComponent = false, schemaResolver } = options;
2853
2895
  let changed = false;
2854
2896
  const neededImports = new Set;
2897
+ const svelteImports = new Set;
2855
2898
  let propsTypeDeclaration = null;
2856
2899
  if (!isComponent) {
2857
- changed = transformOriginCalls(s, source, neededImports) || changed;
2900
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2858
2901
  }
2859
2902
  if (isComponent) {
2860
2903
  const result = await transformAttrsOriginCalls(s, source, neededImports, schemaResolver);
@@ -2867,11 +2910,22 @@ async function transformScriptContent(source, options) {
2867
2910
  if (neededImports.size > 0) {
2868
2911
  const importStatement = generateRuntimeImport([...neededImports]);
2869
2912
  s.prepend(importStatement + `
2913
+ `);
2914
+ }
2915
+ if (svelteImports.size > 0) {
2916
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2917
+ s.prepend(svelteImportStatement + `
2870
2918
  `);
2871
2919
  }
2872
2920
  if (propsTypeDeclaration) {
2873
2921
  const afterImports = findPropsInjectionPosition(source);
2874
- const offset = neededImports.size > 0 ? generateRuntimeImport([...neededImports]).length + 1 : 0;
2922
+ let offset = 0;
2923
+ if (neededImports.size > 0) {
2924
+ offset += generateRuntimeImport([...neededImports]).length + 1;
2925
+ }
2926
+ if (svelteImports.size > 0) {
2927
+ offset += `import { ${[...svelteImports].join(", ")} } from 'svelte'`.length + 1;
2928
+ }
2875
2929
  s.appendLeft(afterImports + offset, propsTypeDeclaration + `
2876
2930
  `);
2877
2931
  }
@@ -1913,7 +1913,7 @@ function parseObjectMembers(source) {
1913
1913
  }
1914
1914
 
1915
1915
  // src/transform/origin-transform.ts
1916
- function transformOriginCalls(s, source, neededImports) {
1916
+ function transformOriginCalls(s, source, neededImports, svelteImports) {
1917
1917
  const regex = /\$origin\s*\(/g;
1918
1918
  let match;
1919
1919
  let changed = false;
@@ -1929,14 +1929,14 @@ function transformOriginCalls(s, source, neededImports) {
1929
1929
  continue;
1930
1930
  }
1931
1931
  const definitionContent = source.slice(openParenIndex + 1, closeParenIndex);
1932
- const transformed = transformOriginDefinition(definitionContent);
1932
+ const transformed = transformOriginDefinition(definitionContent, svelteImports);
1933
1933
  s.overwrite(startIndex, closeParenIndex + 1, `__createOrigin(${transformed})`);
1934
1934
  neededImports.add("__createOrigin");
1935
1935
  changed = true;
1936
1936
  }
1937
1937
  return changed;
1938
1938
  }
1939
- function transformOriginDefinition(content) {
1939
+ function transformOriginDefinition(content, svelteImports) {
1940
1940
  let parents = [];
1941
1941
  let bodyContent = content.trim();
1942
1942
  let initCallback = null;
@@ -2001,7 +2001,7 @@ function transformOriginDefinition(content) {
2001
2001
  }
2002
2002
  }
2003
2003
  const attrDetails = parseAttrsSource(attrsContent);
2004
- const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName);
2004
+ const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName, svelteImports);
2005
2005
  const parentsCode = parents.length > 0 ? `[${parents.join(", ")}]` : "undefined";
2006
2006
  let configCode = `{
2007
2007
  __attrSchema: ${attrSchemaCode},
@@ -2021,22 +2021,48 @@ ${createFnBody}
2021
2021
  }`;
2022
2022
  return configCode;
2023
2023
  }
2024
- function transformOriginBody(content, parents = [], attrDetails = [], propName = "props") {
2024
+ function transformOriginBody(content, parents = [], attrDetails = [], propName = "props", _svelteImports) {
2025
2025
  let body = content.trim();
2026
2026
  const hasParents = parents.length > 0;
2027
- const attrGettersSetters = [];
2028
- for (const attr of attrDetails) {
2029
- if (attr.hasDefault) {
2030
- attrGettersSetters.push(`get ${attr.key}() { return __inputAttrs.${attr.key} ?? ${attr.defaultValue} }`);
2031
- } else {
2032
- attrGettersSetters.push(`get ${attr.key}() { return __inputAttrs.${attr.key} }`);
2027
+ const propsLines = [];
2028
+ if (attrDetails.length > 0) {
2029
+ const initialProps = [];
2030
+ for (const attr of attrDetails) {
2031
+ const defaultExpr = attr.hasDefault ? ` ?? ${attr.defaultValue}` : "";
2032
+ initialProps.push(`${attr.key}: __inputAttrs.${attr.key}${defaultExpr}`);
2033
+ }
2034
+ propsLines.push(`let __props = $state({ ${initialProps.join(", ")} })`);
2035
+ for (const attr of attrDetails) {
2036
+ const defaultExpr = attr.hasDefault ? ` ?? ${attr.defaultValue}` : "";
2037
+ const parentLast = `__last_parent_${attr.key}`;
2038
+ const localLast = `__last_local_${attr.key}`;
2039
+ propsLines.push(`let ${parentLast} = __inputAttrs.${attr.key}`, `let ${localLast} = __props.${attr.key}`, `$effect(() => {
2040
+ ` + ` const __parent = __inputAttrs.${attr.key}
2041
+ ` + ` const __local = __props.${attr.key}
2042
+
2043
+ ` + ` // Parent -> local
2044
+ ` + ` if (__parent !== ${parentLast}) {
2045
+ ` + ` ${parentLast} = __parent
2046
+ ` + ` if (__local !== __parent) {
2047
+ ` + ` __props.${attr.key} = __parent${defaultExpr}
2048
+ ` + ` }
2049
+ ` + ` ${localLast} = __props.${attr.key}
2050
+ ` + ` return
2051
+ ` + ` }
2052
+
2053
+ ` + ` // Local -> parent
2054
+ ` + ` if (__local !== ${localLast}) {
2055
+ ` + ` ${localLast} = __local
2056
+ ` + (attr.bindable ? ` try { __inputAttrs.${attr.key} = __local } catch {}
2057
+ ${parentLast} = __inputAttrs.${attr.key}
2058
+ ` : "") + ` }
2059
+ ` + `})`);
2033
2060
  }
2034
- attrGettersSetters.push(`set ${attr.key}(v) { __inputAttrs.${attr.key} = v }`);
2061
+ } else {
2062
+ propsLines.push("const __props = __inputAttrs");
2035
2063
  }
2036
- const propsObjectCode = attrGettersSetters.length > 0 ? ` const __props = {
2037
- ${attrGettersSetters.join(`,
2038
- `)}
2039
- }` : ` const __props = __inputAttrs`;
2064
+ const propsObjectCode = "\t\t" + propsLines.join(`
2065
+ `);
2040
2066
  if (!body) {
2041
2067
  const baseMembers = [`get ${propName}() { return __props }`];
2042
2068
  if (hasParents)
@@ -2722,9 +2748,10 @@ function transformScript(source, options = {}) {
2722
2748
  const { isComponent = false } = options;
2723
2749
  let changed = false;
2724
2750
  const neededImports = new Set;
2751
+ const svelteImports = new Set;
2725
2752
  let propsTypeDeclaration = null;
2726
2753
  if (!isComponent) {
2727
- changed = transformOriginCalls(s, source, neededImports) || changed;
2754
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2728
2755
  changed = transformStandaloneAttrsCalls(s, source, neededImports) || changed;
2729
2756
  }
2730
2757
  if (isComponent) {
@@ -2763,10 +2790,17 @@ function transformScript(source, options = {}) {
2763
2790
  `);
2764
2791
  }
2765
2792
  }
2766
- } else if (neededImports.size > 0) {
2767
- const importStatement = generateRuntimeImport([...neededImports]);
2768
- s.prepend(importStatement + `
2793
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
2794
+ if (neededImports.size > 0) {
2795
+ const importStatement = generateRuntimeImport([...neededImports]);
2796
+ s.prepend(importStatement + `
2797
+ `);
2798
+ }
2799
+ if (svelteImports.size > 0) {
2800
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2801
+ s.prepend(svelteImportStatement + `
2769
2802
  `);
2803
+ }
2770
2804
  }
2771
2805
  if (!changed) {
2772
2806
  return { code: source, changed: false };
@@ -2785,9 +2819,10 @@ async function transformScriptAsync(source, options) {
2785
2819
  const { isComponent = false, schemaResolver } = options;
2786
2820
  let changed = false;
2787
2821
  const neededImports = new Set;
2822
+ const svelteImports = new Set;
2788
2823
  let propsTypeDeclaration = null;
2789
2824
  if (!isComponent) {
2790
- changed = transformOriginCalls(s, source, neededImports) || changed;
2825
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2791
2826
  changed = transformStandaloneAttrsCalls(s, source, neededImports) || changed;
2792
2827
  }
2793
2828
  if (isComponent) {
@@ -2826,10 +2861,17 @@ async function transformScriptAsync(source, options) {
2826
2861
  `);
2827
2862
  }
2828
2863
  }
2829
- } else if (neededImports.size > 0) {
2830
- const importStatement = generateRuntimeImport([...neededImports]);
2831
- s.prepend(importStatement + `
2864
+ } else if (neededImports.size > 0 || svelteImports.size > 0) {
2865
+ if (neededImports.size > 0) {
2866
+ const importStatement = generateRuntimeImport([...neededImports]);
2867
+ s.prepend(importStatement + `
2868
+ `);
2869
+ }
2870
+ if (svelteImports.size > 0) {
2871
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2872
+ s.prepend(svelteImportStatement + `
2832
2873
  `);
2874
+ }
2833
2875
  }
2834
2876
  if (!changed) {
2835
2877
  return { code: source, changed: false };
@@ -2848,9 +2890,10 @@ async function transformScriptContent(source, options) {
2848
2890
  const { isComponent = false, schemaResolver } = options;
2849
2891
  let changed = false;
2850
2892
  const neededImports = new Set;
2893
+ const svelteImports = new Set;
2851
2894
  let propsTypeDeclaration = null;
2852
2895
  if (!isComponent) {
2853
- changed = transformOriginCalls(s, source, neededImports) || changed;
2896
+ changed = transformOriginCalls(s, source, neededImports, svelteImports) || changed;
2854
2897
  }
2855
2898
  if (isComponent) {
2856
2899
  const result = await transformAttrsOriginCalls(s, source, neededImports, schemaResolver);
@@ -2863,11 +2906,22 @@ async function transformScriptContent(source, options) {
2863
2906
  if (neededImports.size > 0) {
2864
2907
  const importStatement = generateRuntimeImport([...neededImports]);
2865
2908
  s.prepend(importStatement + `
2909
+ `);
2910
+ }
2911
+ if (svelteImports.size > 0) {
2912
+ const svelteImportStatement = `import { ${[...svelteImports].join(", ")} } from 'svelte'`;
2913
+ s.prepend(svelteImportStatement + `
2866
2914
  `);
2867
2915
  }
2868
2916
  if (propsTypeDeclaration) {
2869
2917
  const afterImports = findPropsInjectionPosition(source);
2870
- const offset = neededImports.size > 0 ? generateRuntimeImport([...neededImports]).length + 1 : 0;
2918
+ let offset = 0;
2919
+ if (neededImports.size > 0) {
2920
+ offset += generateRuntimeImport([...neededImports]).length + 1;
2921
+ }
2922
+ if (svelteImports.size > 0) {
2923
+ offset += `import { ${[...svelteImports].join(", ")} } from 'svelte'`.length + 1;
2924
+ }
2871
2925
  s.appendLeft(afterImports + offset, propsTypeDeclaration + `
2872
2926
  `);
2873
2927
  }
@@ -3475,24 +3475,39 @@ function __attrsFor(factory, rawAttrs) {
3475
3475
  const wrapper = {};
3476
3476
  const localValues = {};
3477
3477
  const hasLocalValue = {};
3478
- for (const key2 of Object.keys(schema)) {
3479
- Object.defineProperty(wrapper, key2, {
3478
+ const defineExposedProp = (key2, info) => {
3479
+ if (Object.prototype.hasOwnProperty.call(wrapper, key2))
3480
+ return;
3481
+ const base = {
3480
3482
  get() {
3481
- if (hasLocalValue[key2]) {
3483
+ if (hasLocalValue[key2])
3482
3484
  return localValues[key2];
3483
- }
3484
3485
  return rawAttrs[key2];
3485
3486
  },
3486
- set(value) {
3487
- localValues[key2] = value;
3488
- hasLocalValue[key2] = true;
3489
- try {
3490
- rawAttrs[key2] = value;
3491
- } catch {}
3492
- },
3493
3487
  enumerable: true,
3494
3488
  configurable: true
3495
- });
3489
+ };
3490
+ if (info.bindable) {
3491
+ Object.defineProperty(wrapper, key2, {
3492
+ ...base,
3493
+ set(value) {
3494
+ localValues[key2] = value;
3495
+ hasLocalValue[key2] = true;
3496
+ try {
3497
+ rawAttrs[key2] = value;
3498
+ } catch {}
3499
+ }
3500
+ });
3501
+ } else {
3502
+ Object.defineProperty(wrapper, key2, base);
3503
+ }
3504
+ };
3505
+ for (const [key2, info] of Object.entries(schema)) {
3506
+ const parentValue = rawAttrs[key2];
3507
+ const shouldExpose = !info.bindable || !info.hasDefault || parentValue !== undefined;
3508
+ if (shouldExpose) {
3509
+ defineExposedProp(key2, info);
3510
+ }
3496
3511
  }
3497
3512
  for (const sym of Object.getOwnPropertySymbols(rawAttrs)) {
3498
3513
  Object.defineProperty(wrapper, sym, {
@@ -3505,34 +3520,57 @@ function __attrsFor(factory, rawAttrs) {
3505
3520
  }
3506
3521
  return new Proxy(wrapper, {
3507
3522
  get(target, prop2) {
3508
- if (prop2 in target) {
3509
- return target[prop2];
3523
+ if (typeof prop2 === "string" && prop2 in schema) {
3524
+ if (hasLocalValue[prop2])
3525
+ return localValues[prop2];
3526
+ return rawAttrs[prop2];
3510
3527
  }
3528
+ if (prop2 in target)
3529
+ return target[prop2];
3511
3530
  return rawAttrs[prop2];
3512
3531
  },
3513
3532
  set(target, prop2, value) {
3533
+ if (typeof prop2 === "string" && prop2 in schema) {
3534
+ localValues[prop2] = value;
3535
+ hasLocalValue[prop2] = true;
3536
+ if (!Object.prototype.hasOwnProperty.call(wrapper, prop2)) {
3537
+ defineExposedProp(prop2, schema[prop2]);
3538
+ }
3539
+ if (schema[prop2].bindable) {
3540
+ try {
3541
+ rawAttrs[prop2] = value;
3542
+ } catch {}
3543
+ }
3544
+ return true;
3545
+ }
3514
3546
  if (prop2 in target) {
3515
- target[prop2] = value;
3547
+ try {
3548
+ target[prop2] = value;
3549
+ } catch {}
3516
3550
  return true;
3517
3551
  }
3518
3552
  try {
3519
3553
  rawAttrs[prop2] = value;
3520
3554
  } catch {
3521
- localValues[prop2] = value;
3522
- hasLocalValue[prop2] = true;
3555
+ if (typeof prop2 === "string") {
3556
+ localValues[prop2] = value;
3557
+ hasLocalValue[prop2] = true;
3558
+ }
3523
3559
  }
3524
3560
  return true;
3525
3561
  },
3526
3562
  has(target, prop2) {
3563
+ if (typeof prop2 === "string" && prop2 in schema) {
3564
+ return prop2 in target || hasLocalValue[prop2];
3565
+ }
3527
3566
  return prop2 in target || prop2 in rawAttrs;
3528
3567
  },
3529
3568
  ownKeys() {
3530
3569
  return [...Object.keys(wrapper), ...Object.getOwnPropertySymbols(rawAttrs)];
3531
3570
  },
3532
3571
  getOwnPropertyDescriptor(target, prop2) {
3533
- if (prop2 in target) {
3572
+ if (prop2 in target)
3534
3573
  return Object.getOwnPropertyDescriptor(target, prop2);
3535
- }
3536
3574
  return Object.getOwnPropertyDescriptor(rawAttrs, prop2);
3537
3575
  }
3538
3576
  });
@@ -48,4 +48,4 @@ export interface TransformOriginBodyResult {
48
48
  * })
49
49
  * ```
50
50
  */
51
- export declare function transformOriginCalls(s: MagicString, source: string, neededImports: Set<string>): boolean;
51
+ export declare function transformOriginCalls(s: MagicString, source: string, neededImports: Set<string>, svelteImports?: Set<string>): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-origin",
3
- "version": "1.0.0-next.15",
3
+ "version": "1.0.0-next.17",
4
4
  "description": "Compiler-assisted state and prop ergonomics for Svelte 5",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",