@code3d/core 0.0.1-alpha.6 → 0.0.1-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/bld/chunks/{chunk-T3RAUNSF.js → chunk-4WLVDYUJ.js} +52 -32
- package/bld/chunks/chunk-4WLVDYUJ.js.map +7 -0
- package/bld/chunks/{chunk-KYW4AWKO.js → chunk-C3AJ6WNB.js} +2 -2
- package/bld/chunks/{chunk-3RIMOCPP.js → chunk-TCMEEKWL.js} +2 -2
- package/bld/chunks/{chunk-T6COR2SG.js → chunk-VHSPHJ5F.js} +3 -3
- package/bld/library/cached.d.ts +5 -3
- package/bld/library/cached.d.ts.map +1 -1
- package/bld/library/index.d.ts +2 -2
- package/bld/library/index.d.ts.map +1 -1
- package/bld/library/index.js +3 -3
- package/bld/library/kernel-cache.d.ts +5 -3
- package/bld/library/kernel-cache.d.ts.map +1 -1
- package/bld/library/replicad.js +2 -2
- package/bld/library/runtime.d.ts +4 -4
- package/bld/library/runtime.d.ts.map +1 -1
- package/bld/node/index.js +5 -5
- package/bld/node/replicad.js +4 -4
- package/bld/tooling/index.d.ts +1 -1
- package/bld/tooling/index.d.ts.map +1 -1
- package/bld/tooling/index.js +4 -2
- package/package.json +1 -1
- package/src/library/cached.ts +29 -8
- package/src/library/index.ts +2 -2
- package/src/library/kernel-cache.ts +29 -5
- package/src/library/runtime.ts +17 -6
- package/src/tooling/index.ts +1 -0
- package/bld/chunks/chunk-T3RAUNSF.js.map +0 -7
- /package/bld/chunks/{chunk-KYW4AWKO.js.map → chunk-C3AJ6WNB.js.map} +0 -0
- /package/bld/chunks/{chunk-3RIMOCPP.js.map → chunk-TCMEEKWL.js.map} +0 -0
- /package/bld/chunks/{chunk-T6COR2SG.js.map → chunk-VHSPHJ5F.js.map} +0 -0
package/README.md
CHANGED
|
@@ -194,10 +194,19 @@ Try [mounting-plate.ts](../app/examples/sketches/mounting-plate.ts).
|
|
|
194
194
|
|
|
195
195
|
## Cached computations and custom primitives
|
|
196
196
|
|
|
197
|
-
`
|
|
197
|
+
`cache(fn)` memoizes synchronous, deterministic data computations;
|
|
198
|
+
`cache(fn, args)` immediately returns the cached result for an argument tuple.
|
|
199
|
+
Both forms share the same function identity and argument keys. Supply custom
|
|
200
|
+
codecs in the third argument: `cache(fn, undefined, options)` for a function or
|
|
201
|
+
`cache(fn, args, options)` for a value.
|
|
198
202
|
Pass changing captured state as arguments and treat returned data as immutable.
|
|
199
203
|
Memory hits reuse the retained result; optional `encoder` / `decoder` pairs only
|
|
200
|
-
run when saving to disk or restoring it.
|
|
204
|
+
run when saving to disk or restoring it. Newly computed entries are eligible
|
|
205
|
+
for disk storage when computation reaches the configured threshold (1 ms by
|
|
206
|
+
default). Faster results remain in memory and are not encoded or written on later
|
|
207
|
+
memory hits. Change the threshold in **Settings → Cache** in the App; it applies
|
|
208
|
+
to new computations and preserves existing cache entries. Existing
|
|
209
|
+
disk records can still be restored. The App fingerprints static definitions
|
|
201
210
|
and their dependencies for persistent reuse; dynamic closures and ordinary Node
|
|
202
211
|
calls use function identity for memory reuse. No author cache IDs are needed.
|
|
203
212
|
|
|
@@ -369,6 +369,7 @@ __name(estimateRetainedBytes, "estimateRetainedBytes");
|
|
|
369
369
|
// packages/core/src/library/kernel-cache.ts
|
|
370
370
|
function createComputationCache({
|
|
371
371
|
maximumBytes = 2 * 1024 ** 3,
|
|
372
|
+
minimumPersistenceMilliseconds = 1,
|
|
372
373
|
nativeAllocatedBytes
|
|
373
374
|
}) {
|
|
374
375
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -391,6 +392,10 @@ function createComputationCache({
|
|
|
391
392
|
evictHistoricalEntries();
|
|
392
393
|
}
|
|
393
394
|
__name(setKernelCacheBudget2, "setKernelCacheBudget");
|
|
395
|
+
function setKernelCachePersistenceThreshold2(milliseconds) {
|
|
396
|
+
minimumPersistenceMilliseconds = milliseconds;
|
|
397
|
+
}
|
|
398
|
+
__name(setKernelCachePersistenceThreshold2, "setKernelCachePersistenceThreshold");
|
|
394
399
|
function setKernelExternalBytes2(bytes) {
|
|
395
400
|
externalBytes = bytes;
|
|
396
401
|
evictHistoricalEntries();
|
|
@@ -431,8 +436,10 @@ function createComputationCache({
|
|
|
431
436
|
function evaluateCachedArtifact2(key, lifecycle, compute, codec) {
|
|
432
437
|
const hit = findKernelOperation2(key, lifecycle, codec);
|
|
433
438
|
if (hit) return hit;
|
|
439
|
+
const started = performance.now();
|
|
434
440
|
const value = compute();
|
|
435
|
-
|
|
441
|
+
const milliseconds = performance.now() - started;
|
|
442
|
+
acceptKernelOperation2(key, lifecycle, value, milliseconds, codec);
|
|
436
443
|
return { id: key.id, value };
|
|
437
444
|
}
|
|
438
445
|
__name(evaluateCachedArtifact2, "evaluateCachedArtifact");
|
|
@@ -460,8 +467,8 @@ function createComputationCache({
|
|
|
460
467
|
function lookup(key, lifecycle, codec, read) {
|
|
461
468
|
currentEvaluation?.checkCancelled?.();
|
|
462
469
|
const { id, signature } = key;
|
|
463
|
-
let
|
|
464
|
-
if (!
|
|
470
|
+
let cached = entries.get(id);
|
|
471
|
+
if (!cached && codec !== false) {
|
|
465
472
|
const bytes = read();
|
|
466
473
|
if (bytes) {
|
|
467
474
|
let restored;
|
|
@@ -473,25 +480,26 @@ function createComputationCache({
|
|
|
473
480
|
misses += 1;
|
|
474
481
|
return void 0;
|
|
475
482
|
}
|
|
476
|
-
|
|
483
|
+
cached = retainEntry(key, lifecycle, restored, true);
|
|
477
484
|
persistentHits += 1;
|
|
478
485
|
persisted.add(id);
|
|
479
486
|
}
|
|
480
487
|
}
|
|
481
|
-
if (!
|
|
488
|
+
if (!cached) {
|
|
482
489
|
misses += 1;
|
|
483
490
|
return void 0;
|
|
484
491
|
}
|
|
485
|
-
if (
|
|
492
|
+
if (cached.signature !== signature)
|
|
486
493
|
throw new Error(`Kernel operation cache identity collision: ${id}`);
|
|
487
494
|
hits += 1;
|
|
488
|
-
const value =
|
|
489
|
-
if (codec !== false)
|
|
490
|
-
|
|
495
|
+
const value = cached.instantiate(cached.value);
|
|
496
|
+
if (cached.persistenceEligible && codec !== false)
|
|
497
|
+
persist(key, cached.value, codec, true);
|
|
498
|
+
touchEntry(id, cached);
|
|
491
499
|
return { id, value };
|
|
492
500
|
}
|
|
493
501
|
__name(lookup, "lookup");
|
|
494
|
-
function acceptKernelOperation2(key, lifecycle, value, codec) {
|
|
502
|
+
function acceptKernelOperation2(key, lifecycle, value, milliseconds, codec) {
|
|
495
503
|
const existing = entries.get(key.id);
|
|
496
504
|
if (existing) {
|
|
497
505
|
if (existing.signature !== key.signature)
|
|
@@ -506,8 +514,14 @@ function createComputationCache({
|
|
|
506
514
|
lifecycle.release(value);
|
|
507
515
|
throw error;
|
|
508
516
|
}
|
|
509
|
-
const entry = retainEntry(
|
|
510
|
-
|
|
517
|
+
const entry = retainEntry(
|
|
518
|
+
key,
|
|
519
|
+
lifecycle,
|
|
520
|
+
retained,
|
|
521
|
+
milliseconds >= minimumPersistenceMilliseconds
|
|
522
|
+
);
|
|
523
|
+
if (entry.persistenceEligible && codec !== false)
|
|
524
|
+
persist(key, retained, codec);
|
|
511
525
|
touchEntry(key.id, entry);
|
|
512
526
|
}
|
|
513
527
|
__name(acceptKernelOperation2, "acceptKernelOperation");
|
|
@@ -553,8 +567,9 @@ function createComputationCache({
|
|
|
553
567
|
pendingPersistence.clear();
|
|
554
568
|
}
|
|
555
569
|
__name(flushPendingPersistence, "flushPendingPersistence");
|
|
556
|
-
function retainEntry(key, lifecycle, retained) {
|
|
570
|
+
function retainEntry(key, lifecycle, retained, persistenceEligible) {
|
|
557
571
|
const entry = {
|
|
572
|
+
persistenceEligible,
|
|
558
573
|
estimatedBytes: 256 + estimateRetainedBytes(key.signature) + lifecycle.estimateBytes(retained),
|
|
559
574
|
signature: key.signature,
|
|
560
575
|
value: retained,
|
|
@@ -630,6 +645,7 @@ function createComputationCache({
|
|
|
630
645
|
clearKernelOperationCache: clearKernelOperationCache2,
|
|
631
646
|
kernelOperationCacheStats: kernelOperationCacheStats2,
|
|
632
647
|
setKernelCacheBudget: setKernelCacheBudget2,
|
|
648
|
+
setKernelCachePersistenceThreshold: setKernelCachePersistenceThreshold2,
|
|
633
649
|
setKernelArtifactStore: setKernelArtifactStore2,
|
|
634
650
|
findKernelOperation: findKernelOperation2,
|
|
635
651
|
findKernelOperations: findKernelOperations2,
|
|
@@ -649,6 +665,7 @@ var {
|
|
|
649
665
|
clearKernelOperationCache,
|
|
650
666
|
kernelOperationCacheStats,
|
|
651
667
|
setKernelCacheBudget,
|
|
668
|
+
setKernelCachePersistenceThreshold,
|
|
652
669
|
setKernelArtifactStore,
|
|
653
670
|
findKernelOperation,
|
|
654
671
|
findKernelOperations,
|
|
@@ -713,19 +730,19 @@ var dataLifecycle = {
|
|
|
713
730
|
release() {
|
|
714
731
|
}
|
|
715
732
|
};
|
|
716
|
-
function
|
|
733
|
+
function cache(compute, args, options) {
|
|
717
734
|
const operation = cachedArtifact(
|
|
718
|
-
(...
|
|
719
|
-
const value = compute(...
|
|
735
|
+
(...args2) => {
|
|
736
|
+
const value = compute(...args2);
|
|
720
737
|
if (value && typeof value === "object" && "then" in value && typeof value.then === "function")
|
|
721
|
-
throw new Error("
|
|
738
|
+
throw new Error("cache() requires a synchronous computation.");
|
|
722
739
|
return value;
|
|
723
740
|
},
|
|
724
741
|
{ identity: compute, codec: options }
|
|
725
742
|
);
|
|
726
|
-
return (...
|
|
743
|
+
return args === void 0 ? (...args2) => operation(...args2).value : operation(...args).value;
|
|
727
744
|
}
|
|
728
|
-
__name(
|
|
745
|
+
__name(cache, "cache");
|
|
729
746
|
function cachedArtifact(compute, {
|
|
730
747
|
key,
|
|
731
748
|
lifecycle = dataLifecycle,
|
|
@@ -742,7 +759,7 @@ function cachedArtifact(compute, {
|
|
|
742
759
|
));
|
|
743
760
|
const find = /* @__PURE__ */ __name((key2) => findKernelOperation(key2, lifecycle, persistence), "find");
|
|
744
761
|
const findMany = /* @__PURE__ */ __name((keys) => findKernelOperations(keys, lifecycle, persistence), "findMany");
|
|
745
|
-
const accept = /* @__PURE__ */ __name((key2, value) => acceptKernelOperation(key2, lifecycle, value, persistence), "accept");
|
|
762
|
+
const accept = /* @__PURE__ */ __name((key2, value, milliseconds) => acceptKernelOperation(key2, lifecycle, value, milliseconds, persistence), "accept");
|
|
746
763
|
return Object.assign(
|
|
747
764
|
(...args) => {
|
|
748
765
|
return evaluateCachedArtifact(
|
|
@@ -23375,7 +23392,7 @@ function planModelSnapshotQueries(objects) {
|
|
|
23375
23392
|
sourceRef,
|
|
23376
23393
|
weight: (1 + (input.geometry.topology?.edges.ids.length ?? 0) + (input.geometry.topology?.surfaces.ids.length ?? 0)) * queries.length,
|
|
23377
23394
|
encode: /* @__PURE__ */ __name(() => encodeKernelArtifact(id, input.geometry), "encode"),
|
|
23378
|
-
accept: /* @__PURE__ */ __name((query, value) => snapshotQuery.accept(query.key, value), "accept")
|
|
23395
|
+
accept: /* @__PURE__ */ __name((query, value, milliseconds) => snapshotQuery.accept(query.key, value, milliseconds), "accept")
|
|
23379
23396
|
}));
|
|
23380
23397
|
}
|
|
23381
23398
|
__name(planModelSnapshotQueries, "planModelSnapshotQueries");
|
|
@@ -23389,7 +23406,9 @@ function executeSnapshotQueryBatch(id, bytes, queries, checkCancelled, onResult,
|
|
|
23389
23406
|
onRestore?.(performance.now() - started);
|
|
23390
23407
|
for (const query of queries) {
|
|
23391
23408
|
checkCancelled();
|
|
23392
|
-
|
|
23409
|
+
const started2 = performance.now();
|
|
23410
|
+
const value = computeSnapshotQuery(geometry, query);
|
|
23411
|
+
onResult(query, value, performance.now() - started2);
|
|
23393
23412
|
}
|
|
23394
23413
|
} finally {
|
|
23395
23414
|
geometry.shape.delete();
|
|
@@ -23457,7 +23476,7 @@ var authoringApi = Object.freeze({
|
|
|
23457
23476
|
pivotPoint,
|
|
23458
23477
|
axisEdge,
|
|
23459
23478
|
axisLine,
|
|
23460
|
-
|
|
23479
|
+
cache,
|
|
23461
23480
|
font,
|
|
23462
23481
|
googleFont,
|
|
23463
23482
|
text,
|
|
@@ -23585,15 +23604,15 @@ function evaluateSolidGeometry(operation, arguments_, inputs, compute) {
|
|
|
23585
23604
|
);
|
|
23586
23605
|
}
|
|
23587
23606
|
__name(evaluateSolidGeometry, "evaluateSolidGeometry");
|
|
23588
|
-
function renderMesh(artifact, shape,
|
|
23589
|
-
const
|
|
23590
|
-
if (
|
|
23591
|
-
return
|
|
23607
|
+
function renderMesh(artifact, shape, cache2, tolerance2, topology) {
|
|
23608
|
+
const cached = cache2.get(shape);
|
|
23609
|
+
if (cached) {
|
|
23610
|
+
return cached;
|
|
23592
23611
|
}
|
|
23593
23612
|
const mesh = evaluateSnapshotQuery(
|
|
23594
23613
|
meshQuery(artifact, shape, tolerance2, topology)
|
|
23595
23614
|
);
|
|
23596
|
-
|
|
23615
|
+
cache2.set(shape, mesh);
|
|
23597
23616
|
return mesh;
|
|
23598
23617
|
}
|
|
23599
23618
|
__name(renderMesh, "renderMesh");
|
|
@@ -24655,8 +24674,8 @@ function sketchPointResolver(layers) {
|
|
|
24655
24674
|
const visiting = /* @__PURE__ */ new Set();
|
|
24656
24675
|
const resolve = /* @__PURE__ */ __name((ref) => {
|
|
24657
24676
|
const key = JSON.stringify([ref.layer, ref.id]);
|
|
24658
|
-
const
|
|
24659
|
-
if (
|
|
24677
|
+
const cached = resolved.get(key);
|
|
24678
|
+
if (cached) return cached;
|
|
24660
24679
|
const point3 = points.get(key);
|
|
24661
24680
|
if (!point3) throw new Error(`Missing sketch point ${ref.id}.`);
|
|
24662
24681
|
if (visiting.has(key))
|
|
@@ -25161,10 +25180,11 @@ export {
|
|
|
25161
25180
|
clearKernelOperationCache,
|
|
25162
25181
|
kernelOperationCacheStats,
|
|
25163
25182
|
setKernelCacheBudget,
|
|
25183
|
+
setKernelCachePersistenceThreshold,
|
|
25164
25184
|
setKernelArtifactStore,
|
|
25165
25185
|
setKernelExternalBytes,
|
|
25166
25186
|
identifyCachedFunction,
|
|
25167
|
-
|
|
25187
|
+
cache,
|
|
25168
25188
|
googleFontUrl,
|
|
25169
25189
|
googleFontSources,
|
|
25170
25190
|
installFontEngine,
|
|
@@ -25266,4 +25286,4 @@ export {
|
|
|
25266
25286
|
assertSketchDragConnections,
|
|
25267
25287
|
solveSketchSnapshot
|
|
25268
25288
|
};
|
|
25269
|
-
//# sourceMappingURL=chunk-
|
|
25289
|
+
//# sourceMappingURL=chunk-4WLVDYUJ.js.map
|