@banou/ponyfill 0.0.4 → 0.0.5
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 +12 -4
- package/build/storage.cjs +37 -2
- package/build/storage.js +37 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,10 +58,18 @@ That is not hypothetical. It is why four of ripple's storage eviction tests sat
|
|
|
58
58
|
they filled the origin to provoke that condition, and 3.5 GB of padding left the free figure
|
|
59
59
|
identical to the byte.
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
**The behaviour picked is Firefox's: a ceiling does not rise because you put something under it.**
|
|
62
|
+
`quota` is reported as the lowest the platform has stated for this origin, which needs no probe and
|
|
63
|
+
no user agent sniffing, and invents nothing: the platform really did say the origin could hold that
|
|
64
|
+
much. Two ordinary things are broken by the rising version, and both were seen in ripple:
|
|
65
|
+
`usage / quota` as a gauge never fills, and `quota - usage < floor` never fires, so nothing can
|
|
66
|
+
detect pressure at all.
|
|
67
|
+
|
|
68
|
+
The cost is deliberate and in the safe direction. On Chromium, once bytes are written the reported
|
|
69
|
+
headroom is smaller than what could really be written, so a caller reclaims cache slightly early.
|
|
70
|
+
Cache is the thing that can be fetched again; a caller that never reclaims because it never sees
|
|
71
|
+
pressure is the failure this replaces. The ceiling still follows the platform DOWNWARD, and is never
|
|
72
|
+
reported below the bytes already held, so `quota - usage` reaches zero and never goes negative.
|
|
65
73
|
|
|
66
74
|
## Adding to it
|
|
67
75
|
|
package/build/storage.cjs
CHANGED
|
@@ -66,6 +66,40 @@ var reconcile = (estimate, walked) => {
|
|
|
66
66
|
}
|
|
67
67
|
return Math.max(reported, walked);
|
|
68
68
|
};
|
|
69
|
+
/**
|
|
70
|
+
* The narrowest quota this origin has reported, which is the one that gets reported back.
|
|
71
|
+
*
|
|
72
|
+
* THE DIVERGENCE, AND THE PICK. `quota - usage` already means the same on both engines: bytes you
|
|
73
|
+
* can still write. What diverges is `quota` as a TOTAL, and Chromium never states one. It states
|
|
74
|
+
* `usage + headroom`, recomputed on every read, so the number grows as you fill the origin: measured
|
|
75
|
+
* 10.737 GB rising to 12.353 GB across 1.615 GB written. Firefox states a real total and holds it.
|
|
76
|
+
*
|
|
77
|
+
* Two things a caller does with `quota` are broken by the growing version and neither is exotic:
|
|
78
|
+
*
|
|
79
|
+
* - `usage / quota` as a gauge never fills, because the denominator runs away from the numerator.
|
|
80
|
+
* Ripple showed "2 MB / 10.74 GB" over a library holding 1.78 GB for exactly this reason.
|
|
81
|
+
* - `quota - usage < floor` never fires, so nothing can ever detect pressure. That is what left four
|
|
82
|
+
* of ripple's eviction tests failing for months against a condition that could not occur.
|
|
83
|
+
*
|
|
84
|
+
* So the behaviour picked here is FIREFOX'S: a ceiling, and a ceiling does not rise because you put
|
|
85
|
+
* something under it. It is implemented as the lowest quota seen for this origin, which needs no
|
|
86
|
+
* probe and no user agent sniffing, and it is TRUE in the strong sense: the platform really did say
|
|
87
|
+
* the origin could hold this much, and nothing here invents a number the platform never stated.
|
|
88
|
+
*
|
|
89
|
+
* The cost is deliberate and is in the safe direction. On Chromium, once some bytes are written, the
|
|
90
|
+
* reported headroom is smaller than what could really be written, so a caller reclaims cache
|
|
91
|
+
* slightly early. Cache is the thing that can be fetched again; a caller that never reclaims because
|
|
92
|
+
* it never sees pressure is the failure this replaces.
|
|
93
|
+
*
|
|
94
|
+
* In memory, and per page. Persisting it would mean owning storage to describe storage, and a reload
|
|
95
|
+
* re-anchors on a figure the platform stated at that moment, which is the same guarantee.
|
|
96
|
+
*/
|
|
97
|
+
var narrowest;
|
|
98
|
+
var ceiling = (reported, usage) => {
|
|
99
|
+
if (reported === void 0) return void 0;
|
|
100
|
+
narrowest = narrowest === void 0 ? reported : Math.min(narrowest, reported);
|
|
101
|
+
return Math.max(narrowest, usage ?? 0);
|
|
102
|
+
};
|
|
69
103
|
var storage = {
|
|
70
104
|
/**
|
|
71
105
|
* Same name and same shape as the platform's, with `usage` MEASURED rather than reported.
|
|
@@ -78,10 +112,11 @@ var storage = {
|
|
|
78
112
|
const native = globalThis.navigator?.storage;
|
|
79
113
|
if (!native?.estimate) return {};
|
|
80
114
|
const estimate = await native.estimate();
|
|
81
|
-
const
|
|
115
|
+
const usage = reconcile(estimate, native.getDirectory ? await native.getDirectory().then((directory) => walkBytes(directory)).catch(() => null) : null);
|
|
82
116
|
return {
|
|
83
117
|
...estimate,
|
|
84
|
-
usage
|
|
118
|
+
usage,
|
|
119
|
+
quota: ceiling(estimate.quota, usage)
|
|
85
120
|
};
|
|
86
121
|
},
|
|
87
122
|
persist: () => globalThis.navigator?.storage?.persist?.() ?? Promise.resolve(false),
|
package/build/storage.js
CHANGED
|
@@ -65,6 +65,40 @@ var reconcile = (estimate, walked) => {
|
|
|
65
65
|
}
|
|
66
66
|
return Math.max(reported, walked);
|
|
67
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* The narrowest quota this origin has reported, which is the one that gets reported back.
|
|
70
|
+
*
|
|
71
|
+
* THE DIVERGENCE, AND THE PICK. `quota - usage` already means the same on both engines: bytes you
|
|
72
|
+
* can still write. What diverges is `quota` as a TOTAL, and Chromium never states one. It states
|
|
73
|
+
* `usage + headroom`, recomputed on every read, so the number grows as you fill the origin: measured
|
|
74
|
+
* 10.737 GB rising to 12.353 GB across 1.615 GB written. Firefox states a real total and holds it.
|
|
75
|
+
*
|
|
76
|
+
* Two things a caller does with `quota` are broken by the growing version and neither is exotic:
|
|
77
|
+
*
|
|
78
|
+
* - `usage / quota` as a gauge never fills, because the denominator runs away from the numerator.
|
|
79
|
+
* Ripple showed "2 MB / 10.74 GB" over a library holding 1.78 GB for exactly this reason.
|
|
80
|
+
* - `quota - usage < floor` never fires, so nothing can ever detect pressure. That is what left four
|
|
81
|
+
* of ripple's eviction tests failing for months against a condition that could not occur.
|
|
82
|
+
*
|
|
83
|
+
* So the behaviour picked here is FIREFOX'S: a ceiling, and a ceiling does not rise because you put
|
|
84
|
+
* something under it. It is implemented as the lowest quota seen for this origin, which needs no
|
|
85
|
+
* probe and no user agent sniffing, and it is TRUE in the strong sense: the platform really did say
|
|
86
|
+
* the origin could hold this much, and nothing here invents a number the platform never stated.
|
|
87
|
+
*
|
|
88
|
+
* The cost is deliberate and is in the safe direction. On Chromium, once some bytes are written, the
|
|
89
|
+
* reported headroom is smaller than what could really be written, so a caller reclaims cache
|
|
90
|
+
* slightly early. Cache is the thing that can be fetched again; a caller that never reclaims because
|
|
91
|
+
* it never sees pressure is the failure this replaces.
|
|
92
|
+
*
|
|
93
|
+
* In memory, and per page. Persisting it would mean owning storage to describe storage, and a reload
|
|
94
|
+
* re-anchors on a figure the platform stated at that moment, which is the same guarantee.
|
|
95
|
+
*/
|
|
96
|
+
var narrowest;
|
|
97
|
+
var ceiling = (reported, usage) => {
|
|
98
|
+
if (reported === void 0) return void 0;
|
|
99
|
+
narrowest = narrowest === void 0 ? reported : Math.min(narrowest, reported);
|
|
100
|
+
return Math.max(narrowest, usage ?? 0);
|
|
101
|
+
};
|
|
68
102
|
var storage = {
|
|
69
103
|
/**
|
|
70
104
|
* Same name and same shape as the platform's, with `usage` MEASURED rather than reported.
|
|
@@ -77,10 +111,11 @@ var storage = {
|
|
|
77
111
|
const native = globalThis.navigator?.storage;
|
|
78
112
|
if (!native?.estimate) return {};
|
|
79
113
|
const estimate = await native.estimate();
|
|
80
|
-
const
|
|
114
|
+
const usage = reconcile(estimate, native.getDirectory ? await native.getDirectory().then((directory) => walkBytes(directory)).catch(() => null) : null);
|
|
81
115
|
return {
|
|
82
116
|
...estimate,
|
|
83
|
-
usage
|
|
117
|
+
usage,
|
|
118
|
+
quota: ceiling(estimate.quota, usage)
|
|
84
119
|
};
|
|
85
120
|
},
|
|
86
121
|
persist: () => globalThis.navigator?.storage?.persist?.() ?? Promise.resolve(false),
|