@stream44.studio/encapsulate 0.4.0-rc.11 → 0.4.0-rc.13
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/.dockerignore +3 -0
- package/.github/workflows/test.yaml +2 -2
- package/.o/GordianOpenIntegrity-CurrentLifehash.svg +1024 -1024
- package/.o/GordianOpenIntegrity-InceptionLifehash.svg +1024 -1024
- package/.o/GordianOpenIntegrity.yaml +14 -18
- package/Dockerfile +15 -0
- package/README.md +9 -3
- package/package.json +4 -3
- package/scripts/test-docker.sh +17 -0
- package/src/capsule-projectors/CapsuleModuleProjector.v0.ts +37 -27
- package/src/encapsulate.ts +114 -20
- package/src/spine-contracts/CapsuleSpineContract.v0/Membrane.v0.ts +16 -5
- package/src/spine-contracts/CapsuleSpineContract.v0/Static.v0.ts +10 -5
- package/src/spine-factories/CapsuleSpineFactory.v0.ts +41 -2
- package/src/static-analyzer.v0.ts +13 -4
|
@@ -17,10 +17,11 @@ export class ContractCapsuleInstanceFactory {
|
|
|
17
17
|
protected extendedCapsuleInstance?: any
|
|
18
18
|
protected ownSelf?: any
|
|
19
19
|
protected runtimeSpineContracts?: Record<string, any>
|
|
20
|
+
protected capsuleInstance?: any
|
|
20
21
|
public structInitFunctions: Array<() => any> = []
|
|
21
22
|
public mappedCapsuleInstances: Array<any> = []
|
|
22
23
|
|
|
23
|
-
constructor({ spineContractUri, capsule, self, ownSelf, encapsulatedApi, resolve, importCapsule, spineFilesystemRoot, freezeCapsule, instanceRegistry, extendedCapsuleInstance, runtimeSpineContracts }: { spineContractUri: string, capsule: any, self: any, ownSelf?: any, encapsulatedApi: Record<string, any>, resolve?: (uri: string, parentFilepath: string) => Promise<string>, importCapsule?: (filepath: string) => Promise<any>, spineFilesystemRoot?: string, freezeCapsule?: (capsule: any) => Promise<any>, instanceRegistry?: CapsuleInstanceRegistry, extendedCapsuleInstance?: any, runtimeSpineContracts?: Record<string, any
|
|
24
|
+
constructor({ spineContractUri, capsule, self, ownSelf, encapsulatedApi, resolve, importCapsule, spineFilesystemRoot, freezeCapsule, instanceRegistry, extendedCapsuleInstance, runtimeSpineContracts, capsuleInstance }: { spineContractUri: string, capsule: any, self: any, ownSelf?: any, encapsulatedApi: Record<string, any>, resolve?: (uri: string, parentFilepath: string) => Promise<string>, importCapsule?: (filepath: string) => Promise<any>, spineFilesystemRoot?: string, freezeCapsule?: (capsule: any) => Promise<any>, instanceRegistry?: CapsuleInstanceRegistry, extendedCapsuleInstance?: any, runtimeSpineContracts?: Record<string, any>, capsuleInstance?: any }) {
|
|
24
25
|
this.spineContractUri = spineContractUri
|
|
25
26
|
this.capsule = capsule
|
|
26
27
|
this.self = self
|
|
@@ -33,6 +34,7 @@ export class ContractCapsuleInstanceFactory {
|
|
|
33
34
|
this.instanceRegistry = instanceRegistry
|
|
34
35
|
this.extendedCapsuleInstance = extendedCapsuleInstance
|
|
35
36
|
this.runtimeSpineContracts = runtimeSpineContracts
|
|
37
|
+
this.capsuleInstance = capsuleInstance
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
async mapProperty({ overrides, options, property }: { overrides: any, options: any, property: any }) {
|
|
@@ -40,7 +42,8 @@ export class ContractCapsuleInstanceFactory {
|
|
|
40
42
|
await this.mapMappingProperty({ overrides, options, property })
|
|
41
43
|
} else if (
|
|
42
44
|
property.definition.type === CapsulePropertyTypes.String ||
|
|
43
|
-
property.definition.type === CapsulePropertyTypes.Literal
|
|
45
|
+
property.definition.type === CapsulePropertyTypes.Literal ||
|
|
46
|
+
property.definition.type === CapsulePropertyTypes.Constant
|
|
44
47
|
) {
|
|
45
48
|
this.mapLiteralProperty({ property })
|
|
46
49
|
} else if (property.definition.type === CapsulePropertyTypes.Function) {
|
|
@@ -226,7 +229,8 @@ export class ContractCapsuleInstanceFactory {
|
|
|
226
229
|
const mappedInstance = await mappedCapsule.makeInstance({
|
|
227
230
|
overrides: mappedOverrides,
|
|
228
231
|
options: mappingOptions,
|
|
229
|
-
runtimeSpineContracts: this.runtimeSpineContracts
|
|
232
|
+
runtimeSpineContracts: this.runtimeSpineContracts,
|
|
233
|
+
rootCapsule: this.capsuleInstance?.rootCapsule
|
|
230
234
|
})
|
|
231
235
|
|
|
232
236
|
// Register the instance (replaces null pre-registration marker)
|
|
@@ -369,7 +373,7 @@ export function CapsuleSpineContract({ freezeCapsule, resolve, importCapsule, sp
|
|
|
369
373
|
return {
|
|
370
374
|
'#': CapsuleSpineContract['#'],
|
|
371
375
|
instanceRegistry,
|
|
372
|
-
makeContractCapsuleInstance: ({ spineContractUri, capsule, self, ownSelf, encapsulatedApi, extendedCapsuleInstance, runtimeSpineContracts }: { spineContractUri: string, capsule: any, self: any, ownSelf?: any, encapsulatedApi: Record<string, any>, extendedCapsuleInstance?: any, runtimeSpineContracts?: Record<string, any
|
|
376
|
+
makeContractCapsuleInstance: ({ spineContractUri, capsule, self, ownSelf, encapsulatedApi, extendedCapsuleInstance, runtimeSpineContracts, capsuleInstance }: { spineContractUri: string, capsule: any, self: any, ownSelf?: any, encapsulatedApi: Record<string, any>, extendedCapsuleInstance?: any, runtimeSpineContracts?: Record<string, any>, capsuleInstance?: any }) => {
|
|
373
377
|
return new ContractCapsuleInstanceFactory({
|
|
374
378
|
spineContractUri,
|
|
375
379
|
capsule,
|
|
@@ -382,7 +386,8 @@ export function CapsuleSpineContract({ freezeCapsule, resolve, importCapsule, sp
|
|
|
382
386
|
freezeCapsule,
|
|
383
387
|
instanceRegistry,
|
|
384
388
|
extendedCapsuleInstance,
|
|
385
|
-
runtimeSpineContracts
|
|
389
|
+
runtimeSpineContracts,
|
|
390
|
+
capsuleInstance
|
|
386
391
|
})
|
|
387
392
|
},
|
|
388
393
|
hydrate: ({ capsuleSnapshot }: { capsuleSnapshot: any }): any => {
|
|
@@ -212,9 +212,42 @@ async function resolve(uri: string, fromPath: string, spineRoot?: string): Promi
|
|
|
212
212
|
|
|
213
213
|
// Non-scoped bare specifier — try node_modules resolution from fromPath
|
|
214
214
|
if (!uri.startsWith('.') && !uri.startsWith('/')) {
|
|
215
|
-
//
|
|
215
|
+
// Parse package name and subpath (e.g., "t44/caps/WorkspaceCli" -> pkg="t44", subpath="caps/WorkspaceCli")
|
|
216
|
+
const slashIdx = uri.indexOf('/')
|
|
217
|
+
const pkg = slashIdx === -1 ? uri : uri.slice(0, slashIdx)
|
|
218
|
+
const subpath = slashIdx === -1 ? undefined : uri.slice(slashIdx + 1)
|
|
219
|
+
|
|
220
|
+
// Walk up from fromPath looking for self-package or node_modules
|
|
216
221
|
let dir = dirname(fromPath)
|
|
217
222
|
while (true) {
|
|
223
|
+
// Check if this directory's package.json matches the requested package (self-package resolution)
|
|
224
|
+
try {
|
|
225
|
+
const pjPath = join(dir, 'package.json')
|
|
226
|
+
const pj = JSON.parse(await readFile(pjPath, 'utf-8'))
|
|
227
|
+
if (pj.name === pkg) {
|
|
228
|
+
if (subpath) {
|
|
229
|
+
if (pj.exports) {
|
|
230
|
+
const exportKey = './' + subpath
|
|
231
|
+
const exportValue = pj.exports[exportKey]
|
|
232
|
+
if (typeof exportValue === 'string') {
|
|
233
|
+
return pathResolve(dir, exportValue)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const fsPath = join(dir, subpath + '.ts')
|
|
237
|
+
try { await stat(fsPath); return fsPath } catch { }
|
|
238
|
+
try { await stat(join(dir, subpath)); return join(dir, subpath) } catch { }
|
|
239
|
+
} else if (pj.exports?.['.']) {
|
|
240
|
+
const mainExport = pj.exports['.']
|
|
241
|
+
if (typeof mainExport === 'string') {
|
|
242
|
+
return pathResolve(dir, mainExport)
|
|
243
|
+
}
|
|
244
|
+
} else if (pj.main) {
|
|
245
|
+
return pathResolve(dir, pj.main)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
} catch { }
|
|
249
|
+
|
|
250
|
+
// Check node_modules
|
|
218
251
|
const candidate = join(dir, 'node_modules', uri)
|
|
219
252
|
try {
|
|
220
253
|
const s = await stat(candidate)
|
|
@@ -499,7 +532,7 @@ export async function CapsuleSpineFactory({
|
|
|
499
532
|
|
|
500
533
|
timing?.recordMajor('CAPSULE SPINE FACTORY: READY')
|
|
501
534
|
|
|
502
|
-
const loadCapsule = async ({ capsuleSnapshot }: { capsuleSourceLineRef: string, capsuleSnapshot: any }) => {
|
|
535
|
+
const loadCapsule = async ({ capsuleSnapshot, cacheBustVersion }: { capsuleSourceLineRef: string, capsuleSnapshot: any, cacheBustVersion?: number }) => {
|
|
503
536
|
|
|
504
537
|
if (!capsuleModuleProjectionRoot) {
|
|
505
538
|
throw new Error('capsuleModuleProjectionRoot must be provided to enable dynamic loading of capsules')
|
|
@@ -509,6 +542,11 @@ export async function CapsuleSpineFactory({
|
|
|
509
542
|
|
|
510
543
|
if (!filepath) throw new Error(`Cannot load capsule. No 'filepath' found at 'spineContracts["#@stream44.studio/encapsulate/spine-contracts/CapsuleSpineContract.v0"]["#@stream44.studio/encapsulate/structs/Capsule"].projectedCapsuleFilepath'!`)
|
|
511
544
|
|
|
545
|
+
// Check cache bust version - if it doesn't match, return null to trigger regeneration
|
|
546
|
+
if (cacheBustVersion !== undefined && capsuleSnapshot.cst?.cacheBustVersion !== cacheBustVersion) {
|
|
547
|
+
return null
|
|
548
|
+
}
|
|
549
|
+
|
|
512
550
|
const { capsule } = await import(join(capsuleModuleProjectionRoot, filepath))
|
|
513
551
|
|
|
514
552
|
return capsule
|
|
@@ -529,6 +567,7 @@ export async function CapsuleSpineFactory({
|
|
|
529
567
|
|
|
530
568
|
const result = await SpineRuntime({
|
|
531
569
|
snapshot,
|
|
570
|
+
spineFilesystemRoot,
|
|
532
571
|
spineContracts: spineContractInstances.runtime,
|
|
533
572
|
loadCapsule
|
|
534
573
|
})
|
|
@@ -235,10 +235,18 @@ export function StaticAnalyzer({
|
|
|
235
235
|
])
|
|
236
236
|
|
|
237
237
|
if (cstsContent && crtsContent) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
238
|
+
const cachedCsts = JSON.parse(cstsContent)
|
|
239
|
+
|
|
240
|
+
// Check cache bust version - if mismatch, regenerate
|
|
241
|
+
const cachedVersion = cachedCsts?.[capsuleSourceLineRef]?.cacheBustVersion
|
|
242
|
+
if (encapsulateOptions.cacheBustVersion !== undefined && cachedVersion !== encapsulateOptions.cacheBustVersion) {
|
|
243
|
+
timing?.record(timing?.chalk?.red?.(`StaticAnalyzer: Cache BUST (version mismatch: ${cachedVersion} !== ${encapsulateOptions.cacheBustVersion}) for ${encapsulateOptions.moduleFilepath}`))
|
|
244
|
+
} else {
|
|
245
|
+
timing?.record(`StaticAnalyzer: Cache HIT for ${encapsulateOptions.moduleFilepath}`)
|
|
246
|
+
return {
|
|
247
|
+
csts: cachedCsts,
|
|
248
|
+
crts: JSON.parse(crtsContent)
|
|
249
|
+
}
|
|
242
250
|
}
|
|
243
251
|
}
|
|
244
252
|
}
|
|
@@ -340,6 +348,7 @@ export function StaticAnalyzer({
|
|
|
340
348
|
)
|
|
341
349
|
|
|
342
350
|
const cst: any = {
|
|
351
|
+
cacheBustVersion: encapsulateOptions.cacheBustVersion || 1,
|
|
343
352
|
capsuleSourceLineRef,
|
|
344
353
|
capsuleSourceNameRef,
|
|
345
354
|
capsuleSourceNameRefHash,
|