@stream44.studio/encapsulate 0.2.0-rc.2 → 0.2.0-rc.4

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.

Potentially problematic release.


This version of @stream44.studio/encapsulate might be problematic. Click here for more details.

@@ -49,25 +49,25 @@ async function constructCacheFilePath(moduleFilepath: string, importStackLine: n
49
49
  async function constructNpmUriForCache(absoluteFilepath: string, spineRoot: string): Promise<string | null> {
50
50
  let currentDir = dirname(absoluteFilepath)
51
51
  const maxDepth = 20 // Prevent infinite loops
52
-
52
+
53
53
  for (let i = 0; i < maxDepth; i++) {
54
54
  const packageJsonPath = join(currentDir, 'package.json')
55
-
55
+
56
56
  try {
57
57
  await stat(packageJsonPath)
58
58
  // Found package.json, read it
59
59
  const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8'))
60
60
  const packageName = packageJson.name
61
-
61
+
62
62
  if (!packageName) {
63
63
  // No name in package.json, continue searching
64
64
  currentDir = dirname(currentDir)
65
65
  continue
66
66
  }
67
-
67
+
68
68
  // Get the relative path from the package root to the file
69
69
  const relativeFromPackage = relative(currentDir, absoluteFilepath)
70
-
70
+
71
71
  // Construct npm URI: packageName/relativePath
72
72
  return `${packageName}/${relativeFromPackage}`
73
73
  } catch (error) {
@@ -80,7 +80,7 @@ async function constructNpmUriForCache(absoluteFilepath: string, spineRoot: stri
80
80
  currentDir = parentDir
81
81
  }
82
82
  }
83
-
83
+
84
84
  return null
85
85
  }
86
86
 
@@ -149,17 +149,17 @@ export function CapsuleModuleProjector({
149
149
  })
150
150
  }
151
151
  }
152
-
152
+
153
153
  // If not found in ambient refs, try string-based mapping
154
154
  if (mapped.length === 0 && prop.valueExpression && capsules) {
155
155
  const mappingValue = prop.valueExpression.replace(/['"]/g, '')
156
-
156
+
157
157
  // Look through all capsules to find one that matches
158
158
  for (const [key, potentialCapsule] of Object.entries(capsules)) {
159
159
  if (potentialCapsule === capsule) continue
160
-
160
+
161
161
  const mappedModulePath = potentialCapsule.cst?.source?.moduleFilepath
162
-
162
+
163
163
  if (mappedModulePath && (
164
164
  mappedModulePath === mappingValue ||
165
165
  mappedModulePath.endsWith(mappingValue) ||
@@ -199,17 +199,17 @@ export function CapsuleModuleProjector({
199
199
  foundInAmbient = true
200
200
  }
201
201
  }
202
-
202
+
203
203
  // If not found in ambient refs, try string-based mapping
204
204
  if (!foundInAmbient && nestedProp.valueExpression && capsules) {
205
205
  const mappingValue = nestedProp.valueExpression.replace(/['"]/g, '')
206
-
206
+
207
207
  // Look through all capsules to find one that matches
208
208
  for (const [key, potentialCapsule] of Object.entries(capsules)) {
209
209
  if (potentialCapsule === capsule) continue
210
-
210
+
211
211
  const mappedModulePath = potentialCapsule.cst?.source?.moduleFilepath
212
-
212
+
213
213
  if (mappedModulePath && (
214
214
  mappedModulePath === mappingValue ||
215
215
  mappedModulePath.endsWith(mappingValue) ||
@@ -238,13 +238,13 @@ export function CapsuleModuleProjector({
238
238
  // Helper: Traverse CST to collect all capsule URIs from mappings and property contracts
239
239
  function collectAllCapsuleUris(capsule: any, spineContractUri: string): Set<string> {
240
240
  const uris = new Set<string>()
241
-
241
+
242
242
  function traverseProperties(properties: any) {
243
243
  if (!properties) return
244
-
244
+
245
245
  for (const [key, prop] of Object.entries(properties)) {
246
246
  const propTyped = prop as any
247
-
247
+
248
248
  // Check for Mapping type
249
249
  if (propTyped.type === 'CapsulePropertyTypes.Mapping') {
250
250
  if (propTyped.valueExpression) {
@@ -255,19 +255,19 @@ export function CapsuleModuleProjector({
255
255
  }
256
256
  }
257
257
  }
258
-
258
+
259
259
  // Recursively traverse nested properties
260
260
  if (propTyped.properties) {
261
261
  traverseProperties(propTyped.properties)
262
262
  }
263
263
  }
264
264
  }
265
-
265
+
266
266
  const spineContract = capsule.cst.spineContracts[spineContractUri]
267
267
  if (spineContract?.properties) {
268
268
  traverseProperties(spineContract.properties)
269
269
  }
270
-
270
+
271
271
  return uris
272
272
  }
273
273
 
@@ -277,7 +277,7 @@ export function CapsuleModuleProjector({
277
277
  // Check both top-level and nested under '#' property contract
278
278
  const topLevelProps = spineContract?.properties || {}
279
279
  const nestedProps = spineContract?.properties?.['#']?.properties || {}
280
-
280
+
281
281
  // Check for solidjs.com/standalone specifically
282
282
  for (const key of Object.keys(topLevelProps)) {
283
283
  if (key === 'solidjs.com/standalone') return true
@@ -294,7 +294,7 @@ export function CapsuleModuleProjector({
294
294
  // Check both top-level and nested under '#' property contract
295
295
  const topLevelProps = spineContract?.properties || {}
296
296
  const nestedProps = spineContract?.properties?.['#']?.properties || {}
297
-
297
+
298
298
  // Check for exact match or with suffix
299
299
  for (const key of Object.keys(topLevelProps)) {
300
300
  if (key === 'encapsulate.dev/standalone' || key.startsWith('encapsulate.dev/standalone/')) return true
@@ -312,7 +312,7 @@ export function CapsuleModuleProjector({
312
312
  // Check nested under '#' property contract first, looking for solidjs.com/standalone
313
313
  const nestedProps = spineContract?.properties?.['#']?.properties || {}
314
314
  const topLevelProps = spineContract?.properties || {}
315
-
315
+
316
316
  let solidjsProp = null
317
317
  for (const key of Object.keys(nestedProps)) {
318
318
  if (key === 'solidjs.com/standalone') {
@@ -372,7 +372,7 @@ export function CapsuleModuleProjector({
372
372
  // Check nested under '#' property contract first, looking for encapsulate.dev/standalone or encapsulate.dev/standalone/*
373
373
  const nestedProps = spineContract?.properties?.['#']?.properties || {}
374
374
  const topLevelProps = spineContract?.properties || {}
375
-
375
+
376
376
  let standaloneProp = null
377
377
  for (const key of Object.keys(nestedProps)) {
378
378
  if (key === 'encapsulate.dev/standalone' || key.startsWith('encapsulate.dev/standalone/')) {
@@ -452,7 +452,7 @@ export function CapsuleModuleProjector({
452
452
  const sourceExtension = capsule.cst.source.moduleFilepath?.endsWith('.tsx') ? '.tsx' : '.ts'
453
453
 
454
454
  let projectedPath: string
455
-
455
+
456
456
  // Use capsuleName if it exists (WITHOUT line number), otherwise use capsuleSourceUriLineRef (WITH line number)
457
457
  if (capsule.cst.source.capsuleName) {
458
458
  // Use capsuleName as the path - NO line number
@@ -490,7 +490,16 @@ export function CapsuleModuleProjector({
490
490
  }
491
491
  }
492
492
 
493
- const projectCapsule = async ({ capsule, capsules, snapshotValues, spineContractUri }: { capsule: any, capsules?: Record<string, any>, snapshotValues?: any, spineContractUri: string }): Promise<boolean> => {
493
+ const projectCapsule = async ({ capsule, capsules, snapshotValues, spineContractUri, projectingCapsules }: { capsule: any, capsules?: Record<string, any>, snapshotValues?: any, spineContractUri: string, projectingCapsules?: Set<string> }): Promise<boolean> => {
494
+
495
+ // Check for circular dependency - if already projecting this capsule, skip
496
+ if (projectingCapsules) {
497
+ const capsuleId = capsule.cst?.capsuleSourceNameRefHash || capsule.capsuleSourceLineRef
498
+ if (projectingCapsules.has(capsuleId)) {
499
+ return true
500
+ }
501
+ projectingCapsules.add(capsuleId)
502
+ }
494
503
 
495
504
  timing?.record(`Projector: Start projection for ${capsule.cst.source.moduleFilepath}`)
496
505
 
@@ -580,7 +589,7 @@ export function CapsuleModuleProjector({
580
589
  mappedModulePath.endsWith(mappingValue + '.tsx') ||
581
590
  mappedModulePath.includes(mappingValue.replace('./', ''))
582
591
  )) {
583
- await projectCapsule({ capsule: potentialMappedCapsule, capsules, snapshotValues, spineContractUri })
592
+ await projectCapsule({ capsule: potentialMappedCapsule, capsules, snapshotValues, spineContractUri, projectingCapsules })
584
593
  }
585
594
  }
586
595
  }
@@ -607,7 +616,7 @@ export function CapsuleModuleProjector({
607
616
  // Helper: Rewrite capsule expression to inline CST using regex
608
617
  function rewriteCapsuleExpressionWithCST(targetCapsule: any): string {
609
618
  let expression = targetCapsule.cst.source.capsuleExpression || ''
610
-
619
+
611
620
  const cstJson = JSON.stringify(targetCapsule.cst, null, 4)
612
621
  const crtJson = JSON.stringify(targetCapsule.crt || {}, null, 4)
613
622
  const moduleFilepath = targetCapsule.cst.source.moduleFilepath
@@ -810,7 +819,7 @@ export function CapsuleModuleProjector({
810
819
  if (solidjsComponent) {
811
820
  // Collect all capsule URIs from CST (mappings and property contracts)
812
821
  const allCapsuleUris = collectAllCapsuleUris(capsule, spineContractUri)
813
-
822
+
814
823
  // Also collect from ambient references and build import paths from snapshots
815
824
  const capsuleDeps: Array<{ uri: string, importName: string, importPath: string }> = []
816
825
  for (const [name, ref] of Object.entries(ambientReferences)) {
@@ -819,20 +828,20 @@ export function CapsuleModuleProjector({
819
828
  const snapshot = await buildCapsuleSnapshotForReference(refTyped, capsules, spineContractUri)
820
829
  const capsuleName = snapshot.spineContracts?.['#@stream44.studio/encapsulate/spine-contracts/CapsuleSpineContract.v0']?.['#@stream44.studio/encapsulate/structs/Capsule.v0']?.capsuleName
821
830
  const projectedFilepath = snapshot.spineContracts?.['#@stream44.studio/encapsulate/spine-contracts/CapsuleSpineContract.v0']?.['#@stream44.studio/encapsulate/structs/Capsule.v0']?.projectedCapsuleFilepath
822
-
831
+
823
832
  if (capsuleName && projectedFilepath) {
824
833
  allCapsuleUris.add(capsuleName)
825
-
834
+
826
835
  // Build import path from projected filepath
827
836
  const importName = `_capsule_${capsuleName.replace(/[^a-zA-Z0-9]/g, '_')}`
828
837
  // Remove .~caps/ prefix and strip extension
829
838
  const importPath = projectedFilepath.replace(/^\.~caps\//, '').replace(/\.(ts|tsx)$/, '')
830
-
839
+
831
840
  capsuleDeps.push({ uri: capsuleName, importName, importPath })
832
841
  }
833
842
  }
834
843
  }
835
-
844
+
836
845
  // Generate static imports for all capsule dependencies
837
846
  // Compute relative path from projected file to .~caps directory
838
847
  let importPrefix: string
@@ -844,15 +853,15 @@ export function CapsuleModuleProjector({
844
853
  const relativePathToCaps = relative(projectedFileDir, capsDir)
845
854
  importPrefix = relativePathToCaps.startsWith('.') ? relativePathToCaps : './' + relativePathToCaps
846
855
  }
847
- const capsuleImports = capsuleDeps.map(dep =>
856
+ const capsuleImports = capsuleDeps.map(dep =>
848
857
  `import * as ${dep.importName} from '${importPrefix}/${dep.importPath}'`
849
858
  ).join('\n')
850
-
859
+
851
860
  // Generate capsules map
852
861
  const capsulesMapEntries = capsuleDeps.map(dep =>
853
862
  ` '${dep.uri}': ${dep.importName}`
854
863
  ).join(',\n')
855
-
864
+
856
865
  defaultExport = `
857
866
  ${capsuleImports}
858
867
 
@@ -965,10 +974,10 @@ export default function({ onMembraneEvent }: { onMembraneEvent?: (event: any) =>
965
974
  } else if (hasStandalone) {
966
975
  // Generate a wrapper function that directly invokes the standalone function
967
976
  const capsuleSourceLineRef = capsule.cst.capsuleSourceLineRef
968
-
977
+
969
978
  // Collect all capsule URIs from CST (mappings and property contracts)
970
979
  const allCapsuleUris = collectAllCapsuleUris(capsule, spineContractUri)
971
-
980
+
972
981
  // Also collect from ambient references
973
982
  for (const [name, ref] of Object.entries(ambientReferences)) {
974
983
  const refTyped = ref as any
@@ -980,7 +989,7 @@ export default function({ onMembraneEvent }: { onMembraneEvent?: (event: any) =>
980
989
  }
981
990
  }
982
991
  }
983
-
992
+
984
993
  // Build import paths from snapshots for ALL collected URIs
985
994
  const capsuleDeps: Array<{ uri: string, importName: string, importPath: string }> = []
986
995
  for (const uri of allCapsuleUris) {
@@ -995,22 +1004,22 @@ export default function({ onMembraneEvent }: { onMembraneEvent?: (event: any) =>
995
1004
  }
996
1005
  }
997
1006
  }
998
-
1007
+
999
1008
  if (capsuleRef) {
1000
1009
  const snapshot = await buildCapsuleSnapshotForReference(capsuleRef, capsules, spineContractUri)
1001
1010
  const projectedFilepath = snapshot.spineContracts?.['#@stream44.studio/encapsulate/spine-contracts/CapsuleSpineContract.v0']?.['#@stream44.studio/encapsulate/structs/Capsule.v0']?.projectedCapsuleFilepath
1002
-
1011
+
1003
1012
  if (projectedFilepath) {
1004
1013
  // Build import path from projected filepath
1005
1014
  const importName = `_capsule_${uri.replace(/[^a-zA-Z0-9]/g, '_')}`
1006
1015
  // Remove .~caps/ prefix and strip extension
1007
1016
  const importPath = projectedFilepath.replace(/^\.~caps\//, '').replace(/\.(ts|tsx)$/, '')
1008
-
1017
+
1009
1018
  capsuleDeps.push({ uri, importName, importPath })
1010
1019
  }
1011
1020
  }
1012
1021
  }
1013
-
1022
+
1014
1023
  // Generate static imports for all capsule dependencies
1015
1024
  // Compute relative path from projected file to .~caps directory
1016
1025
  let importPrefix: string
@@ -1022,15 +1031,15 @@ export default function({ onMembraneEvent }: { onMembraneEvent?: (event: any) =>
1022
1031
  const relativePathToCaps = relative(projectedFileDir, capsDir)
1023
1032
  importPrefix = relativePathToCaps.startsWith('.') ? relativePathToCaps : './' + relativePathToCaps
1024
1033
  }
1025
- const capsuleImports = capsuleDeps.map(dep =>
1034
+ const capsuleImports = capsuleDeps.map(dep =>
1026
1035
  `import * as ${dep.importName} from '${importPrefix}/${dep.importPath}'`
1027
1036
  ).join('\n')
1028
-
1037
+
1029
1038
  // Generate capsules map
1030
1039
  const capsulesMapEntries = capsuleDeps.map(dep =>
1031
1040
  ` '${dep.uri}': ${dep.importName}`
1032
1041
  ).join(',\n')
1033
-
1042
+
1034
1043
  defaultExport = `
1035
1044
  ${capsuleImports}
1036
1045
 
@@ -1116,7 +1125,7 @@ ${capsulesMapEntries}
1116
1125
  // Prepare literal references with proper indentation
1117
1126
  const indentedLiteralRefs = literalReferences ? literalReferences.split('\n').map(line => line ? ` ${line}` : '').join('\n') + '\n' : ''
1118
1127
  const indentedInstanceInits = instanceInitializations ? ' ' + instanceInitializations.split('\n').join('\n ') + '\n' : ''
1119
-
1128
+
1120
1129
  const fileContent = `${runtimeImport}${importStatements}
1121
1130
  ${moduleLocalFunctions}
1122
1131
 
@@ -1297,7 +1306,7 @@ ${defaultExport}
1297
1306
 
1298
1307
  // Add runtime imports for SolidJS and standalone functions
1299
1308
  const mappedRuntimeImport = mappedNeedsRuntime ? `"use client"\nimport { Spine, SpineRuntime } from '@stream44.studio/encapsulate/encapsulate'\nimport { CapsuleSpineContract } from '@stream44.studio/encapsulate/spine-contracts/CapsuleSpineContract.v0/Membrane.v0'\n${mappedSolidJsImport}` : ''
1300
-
1309
+
1301
1310
  let mappedDefaultExport = ''
1302
1311
  if (mappedHasSolidJs) {
1303
1312
  // Generate a wrapper that sets up runtime and exports the SolidJS component
@@ -1306,7 +1315,7 @@ ${defaultExport}
1306
1315
  if (solidjsComponent) {
1307
1316
  // Collect all capsule URIs from CST (mappings and property contracts)
1308
1317
  const allMappedCapsuleUris = collectAllCapsuleUris(mappedCapsule, spineContractUri)
1309
-
1318
+
1310
1319
  // Also collect from ambient references
1311
1320
  for (const [name, ref] of Object.entries(mappedAmbientRefs)) {
1312
1321
  const refTyped = ref as any
@@ -1318,7 +1327,7 @@ ${defaultExport}
1318
1327
  }
1319
1328
  }
1320
1329
  }
1321
-
1330
+
1322
1331
  // Build capsule dependencies array
1323
1332
  const mappedCapsuleDeps: Array<{ uri: string, importName: string, importPath: string }> = []
1324
1333
  for (const uri of allMappedCapsuleUris) {
@@ -1327,7 +1336,7 @@ ${defaultExport}
1327
1336
  const importPath = uri.startsWith('@') ? uri.substring(1) : uri
1328
1337
  mappedCapsuleDeps.push({ uri, importName, importPath })
1329
1338
  }
1330
-
1339
+
1331
1340
  // Generate static imports for all capsule dependencies
1332
1341
  // Compute relative path from projected file to .~caps directory
1333
1342
  let importPrefix: string
@@ -1339,15 +1348,15 @@ ${defaultExport}
1339
1348
  const relativePathToCaps = relative(projectedFileDir, capsDir)
1340
1349
  importPrefix = relativePathToCaps.startsWith('.') ? relativePathToCaps : './' + relativePathToCaps
1341
1350
  }
1342
- const mappedCapsuleImports = mappedCapsuleDeps.map(dep =>
1351
+ const mappedCapsuleImports = mappedCapsuleDeps.map(dep =>
1343
1352
  `import * as ${dep.importName} from '${importPrefix}/${dep.importPath}'`
1344
1353
  ).join('\n')
1345
-
1354
+
1346
1355
  // Generate capsules map
1347
1356
  const mappedCapsulesMapEntries = mappedCapsuleDeps.map(dep =>
1348
1357
  ` '${dep.uri}': ${dep.importName}`
1349
1358
  ).join(',\n')
1350
-
1359
+
1351
1360
  mappedDefaultExport = `
1352
1361
  ${mappedCapsuleImports}
1353
1362
 
@@ -1457,10 +1466,10 @@ export default function({ onMembraneEvent }: { onMembraneEvent?: (event: any) =>
1457
1466
  } else if (mappedHasStandalone) {
1458
1467
  // Generate a wrapper function that directly invokes the standalone function
1459
1468
  const mappedCapsuleSourceLineRef = mappedCapsule.cst.capsuleSourceLineRef
1460
-
1469
+
1461
1470
  // Collect all capsule URIs from CST (mappings and property contracts)
1462
1471
  const allMappedCapsuleUris = collectAllCapsuleUris(mappedCapsule, spineContractUri)
1463
-
1472
+
1464
1473
  // Also collect from ambient references
1465
1474
  for (const [name, ref] of Object.entries(mappedAmbientRefs)) {
1466
1475
  const refTyped = ref as any
@@ -1472,7 +1481,7 @@ export default function({ onMembraneEvent }: { onMembraneEvent?: (event: any) =>
1472
1481
  }
1473
1482
  }
1474
1483
  }
1475
-
1484
+
1476
1485
  // Build capsule dependencies array
1477
1486
  const mappedCapsuleDeps: Array<{ uri: string, importName: string, importPath: string }> = []
1478
1487
  for (const uri of allMappedCapsuleUris) {
@@ -1481,7 +1490,7 @@ export default function({ onMembraneEvent }: { onMembraneEvent?: (event: any) =>
1481
1490
  const importPath = uri.startsWith('@') ? uri.substring(1) : uri
1482
1491
  mappedCapsuleDeps.push({ uri, importName, importPath })
1483
1492
  }
1484
-
1493
+
1485
1494
  // Generate static imports for all capsule dependencies
1486
1495
  // Compute relative path from projected file to .~caps directory
1487
1496
  let importPrefix: string
@@ -1493,15 +1502,15 @@ export default function({ onMembraneEvent }: { onMembraneEvent?: (event: any) =>
1493
1502
  const relativePathToCaps = relative(projectedFileDir, capsDir)
1494
1503
  importPrefix = relativePathToCaps.startsWith('.') ? relativePathToCaps : './' + relativePathToCaps
1495
1504
  }
1496
- const mappedCapsuleImports = mappedCapsuleDeps.map(dep =>
1505
+ const mappedCapsuleImports = mappedCapsuleDeps.map(dep =>
1497
1506
  `import * as ${dep.importName} from '${importPrefix}/${dep.importPath}'`
1498
1507
  ).join('\n')
1499
-
1508
+
1500
1509
  // Generate capsules map
1501
1510
  const mappedCapsulesMapEntries = mappedCapsuleDeps.map(dep =>
1502
1511
  ` '${dep.uri}': ${dep.importName}`
1503
1512
  ).join(',\n')
1504
-
1513
+
1505
1514
  mappedDefaultExport = `
1506
1515
  ${mappedCapsuleImports}
1507
1516
 
@@ -1627,7 +1636,7 @@ ${mappedDefaultExport}
1627
1636
  if (registryCapsule === capsule) {
1628
1637
  continue
1629
1638
  }
1630
-
1639
+
1631
1640
  // Skip if this capsule doesn't have the required CST structure
1632
1641
  if (!registryCapsule.cst?.source?.moduleFilepath || !registryCapsule.cst?.source?.importStackLine) {
1633
1642
  continue
@@ -1645,16 +1654,16 @@ ${mappedDefaultExport}
1645
1654
  snapshotData: await buildCapsuleSnapshotForReference({ value: registryCapsule.cst }, capsules, spineContractUri)
1646
1655
  }
1647
1656
  await projectionCacheStore.writeFile(capsuleCacheFilename, JSON.stringify(capsuleCacheData, null, 2))
1648
-
1657
+
1649
1658
  // Also project the capsule to .~caps
1650
1659
  const projectedPath = capsuleCacheData.snapshotData.spineContracts[spineContractUri]['#@stream44.studio/encapsulate/structs/Capsule.v0'].projectedCapsuleFilepath
1651
-
1660
+
1652
1661
  // Generate the capsule file content with proper imports and ambient reference loading
1653
1662
  const capsuleExpression = rewriteCapsuleExpressionWithCST(registryCapsule)
1654
-
1663
+
1655
1664
  // Get ambient references for this capsule
1656
1665
  const capsuleAmbientRefs = registryCapsule.cst.source?.ambientReferences || {}
1657
-
1666
+
1658
1667
  // Generate literal references
1659
1668
  const capsuleLiteralRefs = Object.entries(capsuleAmbientRefs)
1660
1669
  .map(([name, ref]: [string, any]) => {
@@ -1665,7 +1674,7 @@ ${mappedDefaultExport}
1665
1674
  })
1666
1675
  .filter(Boolean)
1667
1676
  .join('\n')
1668
-
1677
+
1669
1678
  // Generate instance initializations for ambient references
1670
1679
  const capsuleInstanceInitPromises = Object.entries(capsuleAmbientRefs)
1671
1680
  .map(async ([name, ref]: [string, any]) => {
@@ -1678,26 +1687,26 @@ ${mappedDefaultExport}
1678
1687
  const capsuleInstanceInits = (await Promise.all(capsuleInstanceInitPromises))
1679
1688
  .filter(Boolean)
1680
1689
  .join('\n ')
1681
-
1690
+
1682
1691
  // Add necessary imports
1683
1692
  const imports = `import { CapsulePropertyTypes } from '@stream44.studio/encapsulate/encapsulate'
1684
1693
  import { makeImportStack } from '@stream44.studio/encapsulate/encapsulate'
1685
1694
  `
1686
-
1695
+
1687
1696
  // Get the capsule name for the assignment
1688
1697
  const capsuleName = registryCapsule.cst.source.capsuleName || ''
1689
-
1698
+
1690
1699
  // Combine literal refs and instance inits with proper indentation
1691
1700
  const indentedLiterals = capsuleLiteralRefs ? capsuleLiteralRefs.split('\n').map(line => ` ${line}`).join('\n') + '\n' : ''
1692
1701
  const indentedInits = capsuleInstanceInits ? ' ' + capsuleInstanceInits + '\n' : ''
1693
-
1702
+
1694
1703
  const capsuleFileContent = `${imports}
1695
1704
  export async function capsule({ encapsulate, loadCapsule }: { encapsulate: any, loadCapsule: any }) {
1696
1705
  ${indentedLiterals}${indentedInits} return ${capsuleExpression}
1697
1706
  }
1698
1707
  capsule['#'] = ${JSON.stringify(capsuleName)}
1699
1708
  `
1700
-
1709
+
1701
1710
  if (projectionStore) {
1702
1711
  await projectionStore.writeFile(projectedPath, capsuleFileContent)
1703
1712
  }