utilium 1.2.8 → 1.2.10
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/cache.d.ts +10 -5
- package/dist/cache.js +69 -6
- package/dist/requests.js +1 -1
- package/package.json +1 -1
- package/src/cache.ts +76 -4
- package/src/requests.ts +1 -1
package/dist/cache.d.ts
CHANGED
@@ -37,20 +37,25 @@ export interface Region {
|
|
37
37
|
export declare class Resource<ID> {
|
38
38
|
/** The resource ID */
|
39
39
|
readonly id: ID;
|
40
|
-
|
41
|
-
size: number;
|
40
|
+
protected _size: number;
|
42
41
|
protected readonly options: Options;
|
43
42
|
/** Regions used to reduce unneeded allocations. Think of sparse arrays. */
|
44
43
|
readonly regions: Region[];
|
44
|
+
/** The full size of the resource */
|
45
|
+
get size(): number;
|
46
|
+
set size(value: number);
|
45
47
|
constructor(
|
46
48
|
/** The resource ID */
|
47
|
-
id: ID,
|
48
|
-
/** The full size of the resource */
|
49
|
-
size: number, options: Options, resources?: Map<ID, Resource<ID> | undefined>);
|
49
|
+
id: ID, _size: number, options: Options, resources?: Map<ID, Resource<ID> | undefined>);
|
50
50
|
/** Combines adjacent regions and combines adjacent ranges within a region */
|
51
51
|
collect(): void;
|
52
52
|
/** Takes an initial range and finds the sub-ranges that are not in the cache */
|
53
53
|
missing(start: number, end: number): Range[];
|
54
|
+
/**
|
55
|
+
* Get the cached sub-ranges of an initial range.
|
56
|
+
* This is conceptually the inverse of `missing`.
|
57
|
+
*/
|
58
|
+
cached(start: number, end: number): Range[];
|
54
59
|
/** Get the region who's ranges include an offset */
|
55
60
|
regionAt(offset: number): Region | undefined;
|
56
61
|
/** Add new data to the cache at given specified offset */
|
package/dist/cache.js
CHANGED
@@ -6,21 +6,49 @@ import { extendBuffer } from './buffer.js';
|
|
6
6
|
*/
|
7
7
|
export class Resource {
|
8
8
|
id;
|
9
|
-
|
9
|
+
_size;
|
10
10
|
options;
|
11
11
|
/** Regions used to reduce unneeded allocations. Think of sparse arrays. */
|
12
12
|
regions = [];
|
13
|
+
/** The full size of the resource */
|
14
|
+
get size() {
|
15
|
+
return this._size;
|
16
|
+
}
|
17
|
+
set size(value) {
|
18
|
+
if (value >= this._size) {
|
19
|
+
this._size = value;
|
20
|
+
return;
|
21
|
+
}
|
22
|
+
this._size = value;
|
23
|
+
for (let i = this.regions.length - 1; i >= 0; i--) {
|
24
|
+
const region = this.regions[i];
|
25
|
+
if (region.offset >= value) {
|
26
|
+
this.regions.splice(i, 1);
|
27
|
+
continue;
|
28
|
+
}
|
29
|
+
const maxLength = value - region.offset;
|
30
|
+
if (region.data.byteLength > maxLength) {
|
31
|
+
region.data = region.data.subarray(0, maxLength);
|
32
|
+
}
|
33
|
+
region.ranges = region.ranges
|
34
|
+
.filter(range => range.start < value)
|
35
|
+
.map(range => {
|
36
|
+
if (range.end > value) {
|
37
|
+
return { start: range.start, end: value };
|
38
|
+
}
|
39
|
+
return range;
|
40
|
+
});
|
41
|
+
}
|
42
|
+
}
|
13
43
|
constructor(
|
14
44
|
/** The resource ID */
|
15
|
-
id,
|
16
|
-
/** The full size of the resource */
|
17
|
-
size, options, resources) {
|
45
|
+
id, _size, options, resources) {
|
18
46
|
this.id = id;
|
19
|
-
this.
|
47
|
+
this._size = _size;
|
20
48
|
this.options = options;
|
21
49
|
options.sparse ??= true;
|
22
50
|
if (!options.sparse)
|
23
|
-
this.regions.push({ offset: 0, data: new Uint8Array(
|
51
|
+
this.regions.push({ offset: 0, data: new Uint8Array(_size), ranges: [] });
|
24
52
|
resources?.set(id, this);
|
25
53
|
}
|
26
54
|
/** Combines adjacent regions and combines adjacent ranges within a region */
|
@@ -83,6 +111,39 @@ export class Resource {
|
|
83
111
|
missingRanges.push({ start, end });
|
84
112
|
return missingRanges;
|
85
113
|
}
|
114
|
+
/**
|
115
|
+
* Get the cached sub-ranges of an initial range.
|
116
|
+
* This is conceptually the inverse of `missing`.
|
117
|
+
*/
|
118
|
+
cached(start, end) {
|
119
|
+
const cachedRanges = [];
|
120
|
+
for (const region of this.regions) {
|
121
|
+
if (region.offset >= end)
|
122
|
+
break;
|
123
|
+
for (const range of region.ranges) {
|
124
|
+
if (range.end <= start)
|
125
|
+
continue;
|
126
|
+
if (range.start >= end)
|
127
|
+
break;
|
128
|
+
cachedRanges.push({
|
129
|
+
start: Math.max(start, range.start),
|
130
|
+
end: Math.min(end, range.end),
|
131
|
+
});
|
132
|
+
}
|
133
|
+
}
|
134
|
+
cachedRanges.sort((a, b) => a.start - b.start);
|
135
|
+
const merged = [];
|
136
|
+
for (const curr of cachedRanges) {
|
137
|
+
const last = merged.at(-1);
|
138
|
+
if (last && curr.start <= last.end) {
|
139
|
+
last.end = Math.max(last.end, curr.end);
|
140
|
+
}
|
141
|
+
else {
|
142
|
+
merged.push(curr);
|
143
|
+
}
|
144
|
+
}
|
145
|
+
return merged;
|
146
|
+
}
|
86
147
|
/** Get the region who's ranges include an offset */
|
87
148
|
regionAt(offset) {
|
88
149
|
if (!this.regions.length)
|
@@ -104,6 +165,7 @@ export class Resource {
|
|
104
165
|
region.data.set(data, offset);
|
105
166
|
region.ranges.push({ start: offset, end });
|
106
167
|
region.ranges.sort((a, b) => a.start - b.start);
|
168
|
+
this.collect();
|
107
169
|
return this;
|
108
170
|
}
|
109
171
|
// Find the correct index to insert the new region
|
@@ -116,6 +178,7 @@ export class Resource {
|
|
116
178
|
else {
|
117
179
|
this.regions.splice(insertIndex, 0, newRegion); // Insert before the first region with a greater offset
|
118
180
|
}
|
181
|
+
this.collect();
|
119
182
|
return this;
|
120
183
|
}
|
121
184
|
}
|
package/dist/requests.js
CHANGED
@@ -116,7 +116,7 @@ export async function set(url, data, options, init = {}) {
|
|
116
116
|
const { offset = 0 } = options;
|
117
117
|
if (!options.cacheOnly)
|
118
118
|
await _fetch(new Request(url, init), { method: 'POST' }, true);
|
119
|
-
resource.add(data, offset)
|
119
|
+
resource.add(data, offset);
|
120
120
|
}
|
121
121
|
/**
|
122
122
|
* Make a DELETE request to remove the resource from the server and clear it from the cache.
|
package/package.json
CHANGED
package/src/cache.ts
CHANGED
@@ -45,16 +45,52 @@ export class Resource<ID> {
|
|
45
45
|
/** Regions used to reduce unneeded allocations. Think of sparse arrays. */
|
46
46
|
public readonly regions: Region[] = [];
|
47
47
|
|
48
|
+
/** The full size of the resource */
|
49
|
+
public get size() {
|
50
|
+
return this._size;
|
51
|
+
}
|
52
|
+
|
53
|
+
public set size(value: number) {
|
54
|
+
if (value >= this._size) {
|
55
|
+
this._size = value;
|
56
|
+
return;
|
57
|
+
}
|
58
|
+
|
59
|
+
this._size = value;
|
60
|
+
|
61
|
+
for (let i = this.regions.length - 1; i >= 0; i--) {
|
62
|
+
const region = this.regions[i];
|
63
|
+
|
64
|
+
if (region.offset >= value) {
|
65
|
+
this.regions.splice(i, 1);
|
66
|
+
continue;
|
67
|
+
}
|
68
|
+
|
69
|
+
const maxLength = value - region.offset;
|
70
|
+
if (region.data.byteLength > maxLength) {
|
71
|
+
region.data = region.data.subarray(0, maxLength);
|
72
|
+
}
|
73
|
+
|
74
|
+
region.ranges = region.ranges
|
75
|
+
.filter(range => range.start < value)
|
76
|
+
.map(range => {
|
77
|
+
if (range.end > value) {
|
78
|
+
return { start: range.start, end: value };
|
79
|
+
}
|
80
|
+
return range;
|
81
|
+
});
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
48
85
|
public constructor(
|
49
86
|
/** The resource ID */
|
50
87
|
public readonly id: ID,
|
51
|
-
|
52
|
-
public size: number,
|
88
|
+
protected _size: number,
|
53
89
|
protected readonly options: Options,
|
54
90
|
resources?: Map<ID, Resource<ID> | undefined>
|
55
91
|
) {
|
56
92
|
options.sparse ??= true;
|
57
|
-
if (!options.sparse) this.regions.push({ offset: 0, data: new Uint8Array(
|
93
|
+
if (!options.sparse) this.regions.push({ offset: 0, data: new Uint8Array(_size), ranges: [] });
|
58
94
|
|
59
95
|
resources?.set(id, this);
|
60
96
|
}
|
@@ -105,7 +141,6 @@ export class Resource<ID> {
|
|
105
141
|
|
106
142
|
for (const range of region.ranges) {
|
107
143
|
if (range.end <= start) continue;
|
108
|
-
|
109
144
|
if (range.start >= end) break;
|
110
145
|
|
111
146
|
if (range.start > start) {
|
@@ -127,6 +162,41 @@ export class Resource<ID> {
|
|
127
162
|
return missingRanges;
|
128
163
|
}
|
129
164
|
|
165
|
+
/**
|
166
|
+
* Get the cached sub-ranges of an initial range.
|
167
|
+
* This is conceptually the inverse of `missing`.
|
168
|
+
*/
|
169
|
+
public cached(start: number, end: number): Range[] {
|
170
|
+
const cachedRanges: Range[] = [];
|
171
|
+
|
172
|
+
for (const region of this.regions) {
|
173
|
+
if (region.offset >= end) break;
|
174
|
+
|
175
|
+
for (const range of region.ranges) {
|
176
|
+
if (range.end <= start) continue;
|
177
|
+
if (range.start >= end) break;
|
178
|
+
|
179
|
+
cachedRanges.push({
|
180
|
+
start: Math.max(start, range.start),
|
181
|
+
end: Math.min(end, range.end),
|
182
|
+
});
|
183
|
+
}
|
184
|
+
}
|
185
|
+
|
186
|
+
cachedRanges.sort((a, b) => a.start - b.start);
|
187
|
+
const merged: Range[] = [];
|
188
|
+
for (const curr of cachedRanges) {
|
189
|
+
const last = merged.at(-1);
|
190
|
+
if (last && curr.start <= last.end) {
|
191
|
+
last.end = Math.max(last.end, curr.end);
|
192
|
+
} else {
|
193
|
+
merged.push(curr);
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
return merged;
|
198
|
+
}
|
199
|
+
|
130
200
|
/** Get the region who's ranges include an offset */
|
131
201
|
public regionAt(offset: number): Region | undefined {
|
132
202
|
if (!this.regions.length) return;
|
@@ -150,6 +220,7 @@ export class Resource<ID> {
|
|
150
220
|
region.ranges.push({ start: offset, end });
|
151
221
|
region.ranges.sort((a, b) => a.start - b.start);
|
152
222
|
|
223
|
+
this.collect();
|
153
224
|
return this;
|
154
225
|
}
|
155
226
|
|
@@ -164,6 +235,7 @@ export class Resource<ID> {
|
|
164
235
|
this.regions.splice(insertIndex, 0, newRegion); // Insert before the first region with a greater offset
|
165
236
|
}
|
166
237
|
|
238
|
+
this.collect();
|
167
239
|
return this;
|
168
240
|
}
|
169
241
|
}
|
package/src/requests.ts
CHANGED
@@ -201,7 +201,7 @@ export async function set(url: string, data: Uint8Array, options: SetOptions, in
|
|
201
201
|
|
202
202
|
if (!options.cacheOnly) await _fetch(new Request(url, init), { method: 'POST' }, true);
|
203
203
|
|
204
|
-
resource.add(data, offset)
|
204
|
+
resource.add(data, offset);
|
205
205
|
}
|
206
206
|
|
207
207
|
/**
|