arcane-os 0.97.0 → 0.97.1
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.97.1
|
|
4
|
+
|
|
5
|
+
- Extract repeated selected TAR members in order, retaining the last complete
|
|
6
|
+
occurrence instead of rejecting valid upstream model companion archives.
|
|
7
|
+
- Preserve earlier extracted files through interrupted replacements and replay
|
|
8
|
+
unfinished archive selections on retry. Completed archive selections remain
|
|
9
|
+
reusable while independent model files resume their own transfers.
|
|
10
|
+
|
|
3
11
|
## 0.97.0
|
|
4
12
|
|
|
5
13
|
- Share native model storage across applications for the same operating-system
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ selected SDK projection or an explicit live SDK source mount. Both profiles
|
|
|
25
25
|
share the theme, packaging, event, cancellation,
|
|
26
26
|
and browser run contracts while retaining their selected application layout.
|
|
27
27
|
|
|
28
|
-
This checkout defines the `0.97.
|
|
28
|
+
This checkout defines the `0.97.1` SDK contract. Development applications declare
|
|
29
29
|
`arcane-os` as `latest` and retain their lockfile. Exact SDK pins begin when Roshi
|
|
30
30
|
designates a production build. Follow [Consumer updates](docs/consumer-updates.md)
|
|
31
31
|
to refresh and compare the installed SDK and lockfile with the published channel;
|
|
@@ -183,6 +183,13 @@ path records select members; a leading `./` is archive path framing. Missing
|
|
|
183
183
|
selected members reject preparation and identify the missing names. Gzip and
|
|
184
184
|
other archive formats are outside this reader's contract.
|
|
185
185
|
|
|
186
|
+
Repeated selected TAR names follow sequential extraction: the last complete
|
|
187
|
+
occurrence replaces the earlier file only after closing its temporary output.
|
|
188
|
+
An interrupted archive pass retains those files and replays its selected
|
|
189
|
+
segments on retry, so an earlier occurrence is never mistaken for the final
|
|
190
|
+
one. Fully completed archive selections are reused while other model files
|
|
191
|
+
continue their own resumable downloads.
|
|
192
|
+
|
|
186
193
|
When the upstream catalog supplies aligned TAR segments, an archive may include
|
|
187
194
|
`ranges:[{start,end,stopBefore?}]`. The reader requests each inclusive HTTP range
|
|
188
195
|
once and parses its TAR framing; `stopBefore` ends that segment before the
|
package/package.json
CHANGED
|
@@ -503,9 +503,8 @@ async function extractTarRange(response, range, selected, found, entry, progress
|
|
|
503
503
|
if (range?.stopBefore && (memberName === range.stopBefore || path.posix.basename(memberName) === range.stopBefore)) break;
|
|
504
504
|
const memberIndexes = selected.get(memberName);
|
|
505
505
|
if (memberIndexes && (type === '0' || type === '\0')) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
506
|
+
// TAR extraction is ordered: a later complete occurrence replaces
|
|
507
|
+
// the earlier file only after its own stream and file close.
|
|
509
508
|
const handles = [];
|
|
510
509
|
const errors = [];
|
|
511
510
|
try {
|
|
@@ -744,6 +743,7 @@ async function acquireNativeMembers(entry) {
|
|
|
744
743
|
state.transports ??= {};
|
|
745
744
|
state.completedMembers = current?.completedMembers ?? [];
|
|
746
745
|
const finished = new Set(state.completedMembers);
|
|
746
|
+
const completedArchiveMembers = new Set(state.completedArchiveMembers ?? []);
|
|
747
747
|
completed = finished.size;
|
|
748
748
|
await mkdir(path.join(selected.root, 'parts'), {recursive: true});
|
|
749
749
|
progress('open');
|
|
@@ -786,17 +786,22 @@ async function acquireNativeMembers(entry) {
|
|
|
786
786
|
let archiveIndex = members.findIndex(function archiveMember(member) { return member.archiveMember !== undefined; });
|
|
787
787
|
for (const archive of entry.archives) {
|
|
788
788
|
const selected = new Map();
|
|
789
|
+
const archiveMembers = [];
|
|
789
790
|
for (const member of archive.members) {
|
|
790
791
|
const memberIndex = archiveIndex++;
|
|
791
|
-
|
|
792
|
+
archiveMembers.push(memberIndex);
|
|
792
793
|
const name = tarName(member.member);
|
|
793
794
|
if (!selected.has(name)) selected.set(name, []);
|
|
794
795
|
selected.get(name).push(memberIndex);
|
|
795
796
|
}
|
|
796
797
|
if (!selected.size) continue;
|
|
798
|
+
if (archiveMembers.every(function confirmed(index) { return finished.has(index) && completedArchiveMembers.has(index); })) continue;
|
|
799
|
+
for (const memberIndex of archiveMembers) completedArchiveMembers.delete(memberIndex);
|
|
797
800
|
jobs.push(async function downloadArchiveMembers() {
|
|
798
801
|
const found = new Set();
|
|
799
802
|
try {
|
|
803
|
+
state.completedArchiveMembers = [...completedArchiveMembers];
|
|
804
|
+
await save();
|
|
800
805
|
for (const range of archive.ranges ?? [undefined]) {
|
|
801
806
|
signal.throwIfAborted();
|
|
802
807
|
const response = await fetchModelResponse(archive.url, signal, range);
|
|
@@ -811,6 +816,11 @@ async function acquireNativeMembers(entry) {
|
|
|
811
816
|
error.members = missing;
|
|
812
817
|
throw error;
|
|
813
818
|
}
|
|
819
|
+
// A file written before a later TAR occurrence is retained
|
|
820
|
+
// on interruption, but only a complete pass confirms reuse.
|
|
821
|
+
for (const memberIndex of archiveMembers) completedArchiveMembers.add(memberIndex);
|
|
822
|
+
state.completedArchiveMembers = [...completedArchiveMembers];
|
|
823
|
+
await save();
|
|
814
824
|
} catch (error) {
|
|
815
825
|
noteFailure(error, error.code?.startsWith('MODEL_ASSET_ARCHIVE_') ? 'failed' : 'interrupted');
|
|
816
826
|
throw error;
|