@kithinji/pod 1.0.14 → 1.0.16

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/main.js CHANGED
@@ -1438,6 +1438,38 @@ var ASTUtilities = class {
1438
1438
  body.push(...statements);
1439
1439
  }
1440
1440
  }
1441
+ addEffectCleanup(scope, effectCall) {
1442
+ const cleanupId = scope.generateUidIdentifier("cleanup");
1443
+ return [
1444
+ // const _cleanup1 = $effect(...)
1445
+ this.t.variableDeclaration("const", [
1446
+ this.t.variableDeclarator(cleanupId, effectCall)
1447
+ ]),
1448
+ // self.__cleanup = [...(self.__cleanup || []), _cleanup1]
1449
+ this.t.expressionStatement(
1450
+ this.t.assignmentExpression(
1451
+ "=",
1452
+ this.t.memberExpression(
1453
+ this.t.identifier("self"),
1454
+ this.t.identifier("__cleanup")
1455
+ ),
1456
+ this.t.arrayExpression([
1457
+ this.t.spreadElement(
1458
+ this.t.logicalExpression(
1459
+ "||",
1460
+ this.t.memberExpression(
1461
+ this.t.identifier("self"),
1462
+ this.t.identifier("__cleanup")
1463
+ ),
1464
+ this.t.arrayExpression([])
1465
+ )
1466
+ ),
1467
+ cleanupId
1468
+ ])
1469
+ )
1470
+ )
1471
+ ];
1472
+ }
1441
1473
  };
1442
1474
  var JSXUtilities = class {
1443
1475
  constructor(t) {
@@ -1629,6 +1661,7 @@ var ElementTransformer = class {
1629
1661
  jsxElement.openingElement.attributes,
1630
1662
  elId,
1631
1663
  statements,
1664
+ scope,
1632
1665
  context2
1633
1666
  );
1634
1667
  if (hasRef && refValue) {
@@ -1758,7 +1791,7 @@ var ElementTransformer = class {
1758
1791
  }
1759
1792
  }
1760
1793
  }
1761
- processDOMAttributes(attributes, elId, statements, context2) {
1794
+ processDOMAttributes(attributes, elId, statements, scope, context2) {
1762
1795
  let hasRef = false;
1763
1796
  let refValue = null;
1764
1797
  let hasDangerousHTML = false;
@@ -1775,14 +1808,20 @@ var ElementTransformer = class {
1775
1808
  context2.observableSignals,
1776
1809
  this.astUtils
1777
1810
  );
1778
- statements.push(
1779
- this.t.expressionStatement(
1811
+ const effectCall = this.t.callExpression(this.t.identifier("$effect"), [
1812
+ this.t.arrowFunctionExpression(
1813
+ [],
1780
1814
  this.t.callExpression(this.t.identifier("$spread"), [
1781
1815
  elId,
1782
1816
  this.astUtils.replaceThisWithSelf(replaced)
1783
1817
  ])
1784
1818
  )
1819
+ ]);
1820
+ const cleanupStatements = this.astUtils.addEffectCleanup(
1821
+ scope,
1822
+ effectCall
1785
1823
  );
1824
+ statements.push(...cleanupStatements);
1786
1825
  continue;
1787
1826
  }
1788
1827
  const key = attr.name.name;
@@ -1825,7 +1864,7 @@ var ElementTransformer = class {
1825
1864
  continue;
1826
1865
  }
1827
1866
  if (key === "style" && this.t.isJSXExpressionContainer(attr.value)) {
1828
- this.processStyleAttribute(attr, elId, statements, context2);
1867
+ this.processStyleAttribute(attr, elId, statements, scope, context2);
1829
1868
  continue;
1830
1869
  }
1831
1870
  this.processRegularAttribute(key, attr, elId, statements, context2);
@@ -1857,7 +1896,7 @@ var ElementTransformer = class {
1857
1896
  )
1858
1897
  );
1859
1898
  }
1860
- processStyleAttribute(attr, elId, statements, context2) {
1899
+ processStyleAttribute(attr, elId, statements, scope, context2) {
1861
1900
  if (!this.t.isJSXExpressionContainer(attr.value)) return;
1862
1901
  this.observableManager.collectObservables(
1863
1902
  attr.value.expression,
@@ -1869,17 +1908,17 @@ var ElementTransformer = class {
1869
1908
  context2.observableSignals,
1870
1909
  this.astUtils
1871
1910
  );
1872
- statements.push(
1873
- this.t.expressionStatement(
1911
+ const effectCall = this.t.callExpression(this.t.identifier("$effect"), [
1912
+ this.t.arrowFunctionExpression(
1913
+ [],
1874
1914
  this.t.callExpression(this.t.identifier("$style"), [
1875
1915
  elId,
1876
- this.t.arrowFunctionExpression(
1877
- [],
1878
- this.astUtils.replaceThisWithSelf(replaced)
1879
- )
1916
+ this.astUtils.replaceThisWithSelf(replaced)
1880
1917
  ])
1881
1918
  )
1882
- );
1919
+ ]);
1920
+ const cleanupStatements = this.astUtils.addEffectCleanup(scope, effectCall);
1921
+ statements.push(...cleanupStatements);
1883
1922
  }
1884
1923
  processRegularAttribute(key, attr, elId, statements, context2) {
1885
1924
  const attrName = key === "className" ? "class" : key;
@@ -2027,7 +2066,8 @@ function j2d({ types: t }) {
2027
2066
  { local: "$createComponent", imported: "createComponent" },
2028
2067
  { local: "$style", imported: "style" },
2029
2068
  { local: "$spread", imported: "spread" },
2030
- { local: "$toSignal", imported: "toSignal" }
2069
+ { local: "$toSignal", imported: "toSignal" },
2070
+ { local: "$effect", imported: "effect" }
2031
2071
  ];
2032
2072
  for (const helper of helpers) {
2033
2073
  path14.unshiftContainer(
@@ -2148,36 +2188,59 @@ function j2d({ types: t }) {
2148
2188
  }
2149
2189
 
2150
2190
  // src/plugins/generators/generate_server_component.ts
2151
- import { parseSync as parseSync3 } from "@swc/core";
2191
+ import { parseSync as parseSync3, printSync as printSync2 } from "@swc/core";
2152
2192
  function generateServerComponent(filePath, code) {
2153
2193
  const ast = parseSync3(code, {
2154
2194
  syntax: "typescript",
2155
2195
  tsx: filePath.endsWith("x"),
2156
2196
  decorators: true
2157
2197
  });
2158
- const componentInfo = extractComponentInfo(ast);
2159
- return generateStubCode(componentInfo);
2160
- }
2161
- function extractComponentInfo(ast) {
2162
- let componentClass = null;
2198
+ const importMap = {};
2163
2199
  for (const item of ast.body) {
2164
- if (item.type === "ExportDeclaration" && item.declaration.type === "ClassDeclaration") {
2200
+ if (item.type === "ImportDeclaration") {
2201
+ const decl = item;
2202
+ for (const specifier of decl.specifiers ?? []) {
2203
+ let localName;
2204
+ if (specifier.type === "ImportSpecifier") {
2205
+ localName = specifier.local.value;
2206
+ } else if (specifier.type === "ImportDefaultSpecifier") {
2207
+ localName = specifier.local.value;
2208
+ } else {
2209
+ continue;
2210
+ }
2211
+ importMap[localName] = decl.source.value;
2212
+ }
2213
+ }
2214
+ }
2215
+ const preservedNodes = [];
2216
+ const stubbedClasses = [];
2217
+ for (const item of ast.body) {
2218
+ let shouldStub = false;
2219
+ if (item.type === "ExportDeclaration" && item.declaration?.type === "ClassDeclaration") {
2165
2220
  const classDecl = item.declaration;
2166
2221
  if (hasComponentDecorator2(classDecl.decorators)) {
2167
- componentClass = classDecl;
2168
- break;
2222
+ shouldStub = true;
2223
+ const stub = extractClassStub2(classDecl);
2224
+ if (stub) {
2225
+ stubbedClasses.push(stub);
2226
+ }
2169
2227
  }
2170
2228
  }
2229
+ if (!shouldStub) {
2230
+ preservedNodes.push(item);
2231
+ }
2171
2232
  }
2172
- if (!componentClass || !componentClass.identifier) {
2173
- throw new Error("Component class is undefined");
2174
- }
2175
- const className = componentClass.identifier.value;
2176
- const methods = extractMethods2(componentClass);
2177
- return {
2178
- className,
2179
- methods
2180
- };
2233
+ const preservedCode = preservedNodes.length > 0 ? printSync2({
2234
+ type: "Module",
2235
+ span: ast.span,
2236
+ body: preservedNodes,
2237
+ interpreter: ast.interpreter
2238
+ }).code : "";
2239
+ const stubCode = stubbedClasses.map((stub) => generateStubCode(stub)).join("\n\n");
2240
+ return `
2241
+ ${preservedCode}
2242
+ ${stubCode}
2243
+ `.trim();
2181
2244
  }
2182
2245
  function hasComponentDecorator2(decorators) {
2183
2246
  if (!decorators) return false;
@@ -2194,6 +2257,111 @@ function hasComponentDecorator2(decorators) {
2194
2257
  return false;
2195
2258
  });
2196
2259
  }
2260
+ function extractClassStub2(classDecl) {
2261
+ const className = classDecl.identifier?.value;
2262
+ if (!className) return null;
2263
+ let propsType = "{}";
2264
+ const decorators = [];
2265
+ const constructorParams = [];
2266
+ if (classDecl.decorators) {
2267
+ for (const dec of classDecl.decorators) {
2268
+ const str = stringifyDecorator2(dec);
2269
+ if (str) decorators.push(str);
2270
+ }
2271
+ }
2272
+ for (const member of classDecl.body) {
2273
+ if (member.type === "ClassProperty") {
2274
+ if (member.key.type === "Identifier" && member.key.value === "props") {
2275
+ propsType = extractPropsType2(member);
2276
+ }
2277
+ } else if (member.type === "Constructor") {
2278
+ for (const param of member.params) {
2279
+ const paramStr = stringifyParam2(param);
2280
+ if (paramStr) constructorParams.push(paramStr);
2281
+ }
2282
+ }
2283
+ }
2284
+ const methods = extractMethods2(classDecl);
2285
+ return {
2286
+ name: className,
2287
+ propsType,
2288
+ decorators,
2289
+ constructorParams,
2290
+ methods
2291
+ };
2292
+ }
2293
+ function stringifyDecorator2(decorator) {
2294
+ const exprCode = printSync2({
2295
+ type: "Module",
2296
+ span: { start: 0, end: 0, ctxt: 0 },
2297
+ body: [
2298
+ {
2299
+ type: "ExpressionStatement",
2300
+ expression: decorator.expression,
2301
+ span: { start: 0, end: 0, ctxt: 0 }
2302
+ }
2303
+ ],
2304
+ interpreter: ""
2305
+ }).code;
2306
+ const cleanCode = exprCode.replace(/^#!.*\n/, "").trim();
2307
+ return `@${cleanCode.replace(/;$/, "")}`;
2308
+ }
2309
+ function extractPropsType2(member) {
2310
+ const typeAnn = member.typeAnnotation?.typeAnnotation;
2311
+ if (!typeAnn) return "{}";
2312
+ if (typeAnn.type === "TsTypeLiteral") {
2313
+ const props = [];
2314
+ for (const m of typeAnn.members) {
2315
+ if (m.type === "TsPropertySignature") {
2316
+ const key = m.key.type === "Identifier" ? m.key.value : "?";
2317
+ const t = m.typeAnnotation ? stringifyType3(m.typeAnnotation.typeAnnotation) : "any";
2318
+ props.push(`${key}: ${t}`);
2319
+ }
2320
+ }
2321
+ return `{ ${props.join("; ")} }`;
2322
+ }
2323
+ return stringifyType3(typeAnn);
2324
+ }
2325
+ function stringifyParam2(param) {
2326
+ let decorators = [];
2327
+ if (param.decorators) {
2328
+ for (const d of param.decorators) {
2329
+ const str = stringifyDecorator2(d);
2330
+ if (str) decorators.push(str);
2331
+ }
2332
+ }
2333
+ const decoratorPrefix = decorators.length ? decorators.join(" ") + " " : "";
2334
+ let typeName = "any";
2335
+ let paramName = "";
2336
+ let accessibility = "";
2337
+ if (param.type === "TsParameterProperty") {
2338
+ accessibility = param.accessibility || "";
2339
+ const inner = param.param;
2340
+ if (inner.type !== "Identifier") return "";
2341
+ paramName = inner.value;
2342
+ if (inner.typeAnnotation?.typeAnnotation) {
2343
+ typeName = extractTypeName2(inner.typeAnnotation.typeAnnotation);
2344
+ }
2345
+ } else if (param.type === "Parameter") {
2346
+ const pat = param.pat;
2347
+ if (pat.type !== "Identifier") return "";
2348
+ paramName = pat.value;
2349
+ if (pat.typeAnnotation?.typeAnnotation) {
2350
+ typeName = extractTypeName2(pat.typeAnnotation.typeAnnotation);
2351
+ }
2352
+ } else {
2353
+ return "";
2354
+ }
2355
+ const accessPrefix = accessibility ? `${accessibility} ` : "";
2356
+ const result = `${decoratorPrefix}${accessPrefix}${paramName}: ${typeName}`;
2357
+ return result;
2358
+ }
2359
+ function extractTypeName2(typeNode) {
2360
+ if (typeNode.type === "TsTypeReference" && typeNode.typeName.type === "Identifier") {
2361
+ return typeNode.typeName.value;
2362
+ }
2363
+ return stringifyType3(typeNode);
2364
+ }
2197
2365
  function extractMethods2(classDecl) {
2198
2366
  const methods = [];
2199
2367
  for (const member of classDecl.body) {
@@ -2283,30 +2451,31 @@ function stringifyType3(typeNode) {
2283
2451
  return "any";
2284
2452
  }
2285
2453
  }
2286
- function generateStubCode(componentInfo) {
2287
- const className = componentInfo.className;
2288
- const build = componentInfo.methods.find((p) => p.name == "build");
2454
+ function generateStubCode(stub) {
2455
+ const className = stub.name;
2456
+ const build = stub.methods.find((p) => p.name == "build");
2289
2457
  if (build == void 0) {
2290
2458
  throw new Error("Component has no build function");
2291
2459
  }
2460
+ const decoratorsStr = stub.decorators.length > 0 ? stub.decorators.join("\n") + "\n" : "";
2292
2461
  return `import {
2293
- Component,
2294
- Inject,
2295
- getCurrentInjector,
2296
- OrcaComponent,
2297
- JSX,
2298
- OSC,
2299
- HttpClient,
2300
- symbolValueReviver
2462
+ Inject as _Inject,
2463
+ getCurrentInjector as _getCurrentInjector,
2464
+ OrcaComponent as _OrcaComponent,
2465
+ JSX as _JSX,
2466
+ OSC as _OSC,
2467
+ HttpClient as _HttpClient,
2468
+ symbolValueReviver as _symbolValueReviver
2301
2469
  } from "@kithinji/orca";
2302
2470
 
2303
- @Component()
2304
- export class ${className} extends OrcaComponent {
2471
+
2472
+ ${decoratorsStr}export class ${className} extends _OrcaComponent {
2305
2473
  props!: any;
2306
2474
 
2307
2475
  constructor(
2308
- @Inject("OSC_URL", { maybe: true }) private oscUrl?: string,
2309
- private readonly http: HttpClient,
2476
+ @_Inject("OSC_URL", { maybe: true }) private oscUrl?: string,
2477
+ private readonly http: _HttpClient,
2478
+ ${stub.constructorParams.join(", ")}
2310
2479
  ) {
2311
2480
  super();
2312
2481
 
@@ -2319,20 +2488,20 @@ export class ${className} extends OrcaComponent {
2319
2488
  const root = document.createElement("div");
2320
2489
  root.textContent = "loading...";
2321
2490
 
2322
- const injector = getCurrentInjector();
2491
+ const injector = _getCurrentInjector();
2323
2492
 
2324
2493
  if(injector == null) {
2325
2494
  throw new Error("Injector is null");
2326
2495
  }
2327
2496
 
2328
- const osc = new OSC(root);
2497
+ const osc = new _OSC(root);
2329
2498
 
2330
- const subscription = this.http.post<JSX.Element>(
2499
+ const subscription = this.http.post<_JSX.Element>(
2331
2500
  \`\${this.oscUrl}?c=${className}\`, {
2332
2501
  body: this.props,
2333
- reviver: symbolValueReviver,
2502
+ reviver: _symbolValueReviver,
2334
2503
  }
2335
- ).subscribe((jsx: JSX.Element) => {
2504
+ ).subscribe((jsx: _JSX.Element) => {
2336
2505
  const action = jsx.action || "insert";
2337
2506
 
2338
2507
  if (action === "insert") {
@@ -4541,7 +4710,7 @@ function printNextSteps(projectName, env, services) {
4541
4710
 
4542
4711
  // src/main.ts
4543
4712
  var program = new Command();
4544
- program.name("pod").description("Pod cli tool").version("1.0.14");
4713
+ program.name("pod").description("Pod cli tool").version("1.0.16");
4545
4714
  program.command("new <name>").description("Start a new Pod Project").action(async (name) => {
4546
4715
  await addNew(name);
4547
4716
  const appDir = path13.resolve(process.cwd(), name);