@pagepocket/lib 0.11.0 → 0.12.0

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.
@@ -15,6 +15,7 @@ export type CaptureTarget = {
15
15
  };
16
16
  import type { PagePocketOptions } from "../types.js";
17
17
  import type { CaptureResult as PagePocketCaptureResult, Plugin as V3Plugin, Unit as V3Unit } from "../units/contracts-bridge.js";
18
+ import type { CaptureOptions } from "../units/types.js";
18
19
  export declare class PagePocket {
19
20
  private target;
20
21
  private options;
@@ -34,5 +35,5 @@ export declare class PagePocket {
34
35
  capture(options: {
35
36
  units: V3Unit[];
36
37
  plugins?: V3Plugin[];
37
- } & import("../units/types.js").CaptureOptions): Promise<PagePocketCaptureResult>;
38
+ } & CaptureOptions): Promise<PagePocketCaptureResult>;
38
39
  }
@@ -33,8 +33,8 @@ export const replayCssProxy = {
33
33
  if (!next) {
34
34
  return full;
35
35
  }
36
- const q = quote || "";
37
- return "url(" + q + next + q + ")";
36
+ const quoteSymbol = quote || "";
37
+ return "url(" + quoteSymbol + next + quoteSymbol + ")";
38
38
  } catch {
39
39
  return full;
40
40
  }
package/dist/kind-map.js CHANGED
@@ -42,17 +42,13 @@ export const requiredEntryKindError = (unitName, requiredKind, entry) => {
42
42
  * Convenience handler for `mapKind` that throws a standardized
43
43
  * "does not support entry kind" error.
44
44
  */
45
- export const throwUnsupportedEntryKind = (unitName) => {
46
- return (_kind, entry) => {
47
- throw unsupportedEntryKindError(unitName, entry);
48
- };
45
+ export const throwUnsupportedEntryKind = (unitName) => (_kind, entry) => {
46
+ throw unsupportedEntryKindError(unitName, entry);
49
47
  };
50
48
  /**
51
49
  * Convenience handler for `mapKind` that throws a standardized
52
50
  * "requires entry kind" error.
53
51
  */
54
- export const throwRequiredEntryKind = (unitName, requiredKind) => {
55
- return (_kind, entry) => {
56
- throw requiredEntryKindError(unitName, requiredKind, entry);
57
- };
52
+ export const throwRequiredEntryKind = (unitName, requiredKind) => (_kind, entry) => {
53
+ throw requiredEntryKindError(unitName, requiredKind, entry);
58
54
  };
@@ -3,9 +3,7 @@ const defaultApply = {
3
3
  limit: "all",
4
4
  onReplaced: "stop"
5
5
  };
6
- const isPlainObject = (value) => {
7
- return typeof value === "object" && value !== null;
8
- };
6
+ const isPlainObject = (value) => typeof value === "object" && value !== null;
9
7
  const normalizeApply = (apply) => ({
10
8
  scope: apply?.scope ?? defaultApply.scope,
11
9
  limit: apply?.limit ?? defaultApply.limit,
@@ -7,19 +7,19 @@ const runFnRuleOnSelection = async (input) => {
7
7
  const selection = $(item.query).toArray();
8
8
  const limit = item.apply.limit;
9
9
  const max = limit === "all" ? selection.length : Math.max(0, limit);
10
- for (let i = 0; i < selection.length && i < max; i += 1) {
11
- const el = selection[i];
12
- const $el = $(el);
13
- if (!isHtmlElement($, $el)) {
10
+ for (let selectionIndex = 0; selectionIndex < selection.length && selectionIndex < max; selectionIndex += 1) {
11
+ const selectedElement = selection[selectionIndex];
12
+ const $selectedElement = $(selectedElement);
13
+ if (!isHtmlElement($, $selectedElement)) {
14
14
  continue;
15
15
  }
16
16
  const ctx = {
17
17
  $,
18
- $el,
18
+ $el: $selectedElement,
19
19
  url: input.url,
20
20
  entryUrl: input.entryUrl,
21
21
  ruleIndex: item.ruleIndex,
22
- matchIndex: i
22
+ matchIndex: selectionIndex
23
23
  };
24
24
  const result = await item.run(ctx);
25
25
  if (!result) {
@@ -27,7 +27,7 @@ const runFnRuleOnSelection = async (input) => {
27
27
  }
28
28
  const actions = Array.isArray(result) ? result : [result];
29
29
  for (const action of actions) {
30
- applyReplaceAction($, $el, action);
30
+ applyReplaceAction($, $selectedElement, action);
31
31
  }
32
32
  }
33
33
  };
@@ -56,22 +56,22 @@ export const applyReplaceElements = async (input) => {
56
56
  const limit = item.apply.limit;
57
57
  const max = limit === "all" ? selection.length : Math.max(0, limit);
58
58
  let replacedCount = 0;
59
- for (let i = 0; i < selection.length && replacedCount < max; i += 1) {
60
- const el = selection[i];
61
- if (item.apply.onReplaced === "stop" && replacedByIndex.has(el)) {
59
+ for (let selectionIndex = 0; selectionIndex < selection.length && replacedCount < max; selectionIndex += 1) {
60
+ const selectedElementIdentity = selection[selectionIndex];
61
+ if (item.apply.onReplaced === "stop" && replacedByIndex.has(selectedElementIdentity)) {
62
62
  continue;
63
63
  }
64
- const $el = input.$(selection[i]);
65
- if (!isHtmlElement(input.$, $el)) {
64
+ const $selectedElement = input.$(selection[selectionIndex]);
65
+ if (!isHtmlElement(input.$, $selectedElement)) {
66
66
  continue;
67
67
  }
68
- if (!elementMatchesFilter(input.$, $el, filter)) {
68
+ if (!elementMatchesFilter(input.$, $selectedElement, filter)) {
69
69
  continue;
70
70
  }
71
- applyReplaceAction(input.$, $el, item.rule.replace);
71
+ applyReplaceAction(input.$, $selectedElement, item.rule.replace);
72
72
  replacedCount += 1;
73
73
  if (item.apply.onReplaced === "stop") {
74
- replacedByIndex.add(el);
74
+ replacedByIndex.add(selectedElementIdentity);
75
75
  }
76
76
  }
77
77
  }
@@ -1,6 +1,4 @@
1
- const looksAlreadyEscapedForStaticServers = (value) => {
2
- return /%25[0-9a-fA-F]{2}/.test(value);
3
- };
1
+ const looksAlreadyEscapedForStaticServers = (value) => /%25[0-9a-fA-F]{2}/.test(value);
4
2
  export const escapePercentForStaticServersOnce = (value) => {
5
3
  if (!value) {
6
4
  return value;
@@ -14,19 +14,19 @@ const encodeEmbeddedUrlTailIfPresent = (pathname) => {
14
14
  return undefined;
15
15
  }
16
16
  const parts = raw.split("/");
17
- for (let i = 0; i < parts.length; i += 1) {
18
- const scheme = parts[i];
17
+ for (let partIndex = 0; partIndex < parts.length; partIndex += 1) {
18
+ const scheme = parts[partIndex];
19
19
  if (scheme !== "http:" && scheme !== "https:") {
20
20
  continue;
21
21
  }
22
- const hasDoubleSlash = parts[i + 1] === "";
23
- const host = parts[i + 2] || "";
22
+ const hasDoubleSlash = parts[partIndex + 1] === "";
23
+ const host = parts[partIndex + 2] || "";
24
24
  if (!hasDoubleSlash || !isLikelyHostname(host)) {
25
25
  continue;
26
26
  }
27
- const embedded = scheme + "//" + parts.slice(i + 2).join("/");
27
+ const embedded = scheme + "//" + parts.slice(partIndex + 2).join("/");
28
28
  const encoded = encodeURIComponent(embedded);
29
- const nextParts = parts.slice(0, i).concat(encoded);
29
+ const nextParts = parts.slice(0, partIndex).concat(encoded);
30
30
  const rebuilt = nextParts.join("/") || "/";
31
31
  return rebuilt.startsWith("/") ? rebuilt : "/" + rebuilt;
32
32
  }
@@ -92,7 +92,7 @@ const preferSingle = (items, baseUrl, suffixLength) => {
92
92
  }
93
93
  })();
94
94
  if (baseParsed) {
95
- const sameOrigin = items.filter((i) => i.parsed.origin === baseParsed.origin);
95
+ const sameOrigin = items.filter((indexedItem) => indexedItem.parsed.origin === baseParsed.origin);
96
96
  if (sameOrigin.length === 1) {
97
97
  return sameOrigin[0];
98
98
  }
@@ -120,9 +120,9 @@ const tryCandidates = (items, baseUrl, suffixLength) => {
120
120
  const makeSuffixes = (pathname) => {
121
121
  const parts = pathname.split("/").filter(Boolean);
122
122
  const out = [];
123
- for (let i = 0; i < parts.length; i += 1) {
124
- const suffix = "/" + parts.slice(i).join("/");
125
- out.push({ key: suffix, depth: parts.length - i });
123
+ for (let partIndex = 0; partIndex < parts.length; partIndex += 1) {
124
+ const suffix = "/" + parts.slice(partIndex).join("/");
125
+ out.push({ key: suffix, depth: parts.length - partIndex });
126
126
  }
127
127
  return out;
128
128
  };
@@ -175,7 +175,7 @@ export const resolveToLocalPath = (options) => {
175
175
  const pathname = abs.pathname || "/";
176
176
  const pathnameVariants = makePathnameVariants(pathname);
177
177
  const search = abs.search || "";
178
- const pathnameWithSearchVariants = pathnameVariants.map((p) => p + search);
178
+ const pathnameWithSearchVariants = pathnameVariants.map((pathnameVariant) => pathnameVariant + search);
179
179
  for (const key of pathnameWithSearchVariants) {
180
180
  const items = toArray(index.byPathnameWithSearch.get(key));
181
181
  const match = tryCandidates(items, baseUrl, 99);
@@ -24,7 +24,7 @@ const isDescriptorToken = (token) => {
24
24
  const parseSrcset = (input) => {
25
25
  const rawCandidates = input
26
26
  .split(",")
27
- .map((c) => c.trim())
27
+ .map((candidateText) => candidateText.trim())
28
28
  .filter(Boolean);
29
29
  return rawCandidates.map((candidate) => {
30
30
  const tokens = candidate.split(/\s+/).filter(Boolean);
@@ -40,26 +40,24 @@ const parseSrcset = (input) => {
40
40
  return { url: candidate };
41
41
  });
42
42
  };
43
- const stringifySrcset = (candidates) => {
44
- return candidates
45
- .map((c) => {
46
- const url = c.url.trim();
47
- if (!c.descriptor) {
48
- return url;
49
- }
50
- return `${url} ${c.descriptor.trim()}`;
51
- })
52
- .filter(Boolean)
53
- .join(",");
54
- };
43
+ const stringifySrcset = (candidates) => candidates
44
+ .map((candidate) => {
45
+ const url = candidate.url.trim();
46
+ if (!candidate.descriptor) {
47
+ return url;
48
+ }
49
+ return `${url} ${candidate.descriptor.trim()}`;
50
+ })
51
+ .filter(Boolean)
52
+ .join(",");
55
53
  export const rewriteSrcsetValue = (value, baseUrl, resolve) => {
56
54
  if (isUnsafeSrcsetValue(value)) {
57
55
  return "";
58
56
  }
59
57
  const candidates = parseSrcset(value);
60
- const rewritten = candidates.map((c) => {
61
- const resolved = resolveUrlValue(c.url, baseUrl, resolve);
62
- return { url: resolved ?? c.url, descriptor: c.descriptor };
58
+ const rewritten = candidates.map((candidate) => {
59
+ const resolved = resolveUrlValue(candidate.url, baseUrl, resolve);
60
+ return { url: resolved ?? candidate.url, descriptor: candidate.descriptor };
63
61
  });
64
62
  return stringifySrcset(rewritten);
65
63
  };
@@ -1,7 +1,7 @@
1
1
  export const headersListToRecord = (headers) => {
2
2
  const out = {};
3
- for (const h of headers) {
4
- out[h.name] = h.value;
3
+ for (const header of headers) {
4
+ out[header.name] = header.value;
5
5
  }
6
6
  return out;
7
7
  };
@@ -1,16 +1,15 @@
1
1
  import { sanitizePosixPath } from "../utils.js";
2
- export const escapePercentForStaticServers = (value) => {
3
- // Many static servers decode percent-encoding in the request path before
4
- // resolving it to a filesystem path.
5
- //
6
- // Our snapshots can contain literal "%2F" sequences in filenames (e.g.
7
- // Substack image URLs embedded into a path segment). When a server decodes
8
- // "%2F" to "/", it changes the path structure and causes 404s.
9
- //
10
- // Escaping "%" to "%25" makes the request decode back to the original
11
- // filename on disk.
12
- return value.split("%").join("%25");
13
- };
2
+ export const escapePercentForStaticServers = (value) =>
3
+ // Many static servers decode percent-encoding in the request path before
4
+ // resolving it to a filesystem path.
5
+ //
6
+ // Our snapshots can contain literal "%2F" sequences in filenames (e.g.
7
+ // Substack image URLs embedded into a path segment). When a server decodes
8
+ // "%2F" to "/", it changes the path structure and causes 404s.
9
+ //
10
+ // Escaping "%" to "%25" makes the request decode back to the original
11
+ // filename on disk.
12
+ value.split("%").join("%25");
14
13
  export const docDirFromUrl = (url) => {
15
14
  try {
16
15
  const parsed = new URL(url);
@@ -1,4 +1,5 @@
1
1
  import type { ChannelToken, ReplaceElementsConfig } from "@pagepocket/contracts";
2
+ import type { CaptureOptions, EntryInfo, PagePocketOptions } from "./types.js";
2
3
  export type CaptureResult = {
3
4
  kind: "raw";
4
5
  outputDir: string;
@@ -46,9 +47,9 @@ export interface ElementPatchRegistry {
46
47
  compile(): Promise<ReplaceElementsConfig>;
47
48
  }
48
49
  export interface UnitRuntime {
49
- readonly entry: import("./types.js").EntryInfo;
50
- readonly options: import("./types.js").CaptureOptions;
51
- readonly pocketOptions: import("./types.js").PagePocketOptions;
50
+ readonly entry: EntryInfo;
51
+ readonly options: CaptureOptions;
52
+ readonly pocketOptions: PagePocketOptions;
52
53
  publish<T>(t: ChannelToken<T>, value: T): void;
53
54
  subscribe<T>(t: ChannelToken<T>): AsyncIterable<T>;
54
55
  hasPublisher(t: ChannelToken<unknown>): boolean;
@@ -56,8 +57,8 @@ export interface UnitRuntime {
56
57
  defer(promise: DeferredHandle): void;
57
58
  }
58
59
  export interface PluginHost {
59
- readonly entry: import("./types.js").EntryInfo;
60
- readonly options: import("./types.js").CaptureOptions;
60
+ readonly entry: EntryInfo;
61
+ readonly options: CaptureOptions;
61
62
  subscribe<T>(t: ChannelToken<T>): AsyncIterable<T>;
62
63
  hasPublisher(t: ChannelToken<unknown>): boolean;
63
64
  readonly elements: ElementPatchRegistry;
@@ -35,11 +35,11 @@ export class AsyncQueue {
35
35
  async *iterate() {
36
36
  while (true) {
37
37
  if (this.values.length > 0) {
38
- const v = this.values.shift();
39
- if (v === undefined) {
38
+ const value = this.values.shift();
39
+ if (value === undefined) {
40
40
  continue;
41
41
  }
42
- yield v;
42
+ yield value;
43
43
  continue;
44
44
  }
45
45
  if (this.done) {
@@ -25,11 +25,11 @@ export declare class RuntimeImpl implements UnitRuntime {
25
25
  options: CaptureOptions;
26
26
  pocketOptions: PagePocketOptions;
27
27
  });
28
- publish<T>(t: ChannelToken<T>, value: T): void;
29
- subscribe<T>(t: ChannelToken<T>): AsyncIterable<T>;
30
- hasPublisher(t: ChannelToken<unknown>): boolean;
28
+ publish<T>(channelToken: ChannelToken<T>, value: T): void;
29
+ subscribe<T>(channelToken: ChannelToken<T>): AsyncIterable<T>;
30
+ hasPublisher(channelToken: ChannelToken<unknown>): boolean;
31
31
  defer(promise: Promise<unknown>): void;
32
- _ensureChannel(t: ChannelToken<unknown>): void;
32
+ _ensureChannel(channelToken: ChannelToken<unknown>): void;
33
33
  _closeAllChannels(): Promise<void>;
34
34
  _awaitDeferred(): Promise<void>;
35
35
  }
@@ -35,8 +35,8 @@ export class RuntimeImpl {
35
35
  this.options = input.options;
36
36
  this.pocketOptions = input.pocketOptions;
37
37
  }
38
- publish(t, value) {
39
- const state = this.channels.get(t.id);
38
+ publish(channelToken, value) {
39
+ const state = this.channels.get(channelToken.id);
40
40
  if (!state || state.closed) {
41
41
  return;
42
42
  }
@@ -45,45 +45,45 @@ export class RuntimeImpl {
45
45
  sub.push(value);
46
46
  }
47
47
  }
48
- subscribe(t) {
49
- if (!this.channels.has(t.id)) {
50
- this.channels.set(t.id, { hasPublisher: false, subs: new Set(), closed: false });
48
+ subscribe(channelToken) {
49
+ if (!this.channels.has(channelToken.id)) {
50
+ this.channels.set(channelToken.id, { hasPublisher: false, subs: new Set(), closed: false });
51
51
  }
52
- const state = this.channels.get(t.id);
52
+ const state = this.channels.get(channelToken.id);
53
53
  if (!state || state.closed) {
54
54
  return emptyAsyncIterable();
55
55
  }
56
- const q = new AsyncQueue();
56
+ const queue = new AsyncQueue();
57
57
  const sub = {
58
- push: (v) => q.push(v),
59
- close: () => q.close()
58
+ push: (value) => queue.push(value),
59
+ close: () => queue.close()
60
60
  };
61
61
  state.subs.add(sub);
62
62
  const owner = this;
63
63
  return (async function* () {
64
64
  try {
65
- for await (const v of q.iterate()) {
66
- yield v;
65
+ for await (const value of queue.iterate()) {
66
+ yield value;
67
67
  }
68
68
  }
69
69
  finally {
70
- const s = owner.channels.get(t.id);
71
- s?.subs.delete(sub);
72
- q.close();
70
+ const channelState = owner.channels.get(channelToken.id);
71
+ channelState?.subs.delete(sub);
72
+ queue.close();
73
73
  }
74
74
  })();
75
75
  }
76
- hasPublisher(t) {
77
- return this.channels.get(t.id)?.hasPublisher === true;
76
+ hasPublisher(channelToken) {
77
+ return this.channels.get(channelToken.id)?.hasPublisher === true;
78
78
  }
79
79
  defer(promise) {
80
80
  this.deferred.add(promise);
81
81
  }
82
- _ensureChannel(t) {
83
- if (this.channels.has(t.id)) {
82
+ _ensureChannel(channelToken) {
83
+ if (this.channels.has(channelToken.id)) {
84
84
  return;
85
85
  }
86
- this.channels.set(t.id, { hasPublisher: false, subs: new Set(), closed: false });
86
+ this.channels.set(channelToken.id, { hasPublisher: false, subs: new Set(), closed: false });
87
87
  }
88
88
  async _closeAllChannels() {
89
89
  for (const state of this.channels.values()) {
@@ -103,11 +103,11 @@ export class RuntimeImpl {
103
103
  }
104
104
  export const mergePatchIntoFreshContext = (patch) => {
105
105
  const next = { value: {} };
106
- for (const [k, v] of Object.entries(patch)) {
107
- if (k === TERMINAL_RESULT_KEY) {
106
+ for (const [key, value] of Object.entries(patch)) {
107
+ if (key === TERMINAL_RESULT_KEY) {
108
108
  continue;
109
109
  }
110
- next.value[k] = v;
110
+ next.value[key] = value;
111
111
  }
112
112
  return next;
113
113
  };
@@ -6,27 +6,25 @@ export const runCapture = async (input) => {
6
6
  options: input.options,
7
7
  pocketOptions: input.pocketOptions
8
8
  });
9
- for (const ch of input.declaredChannels ?? []) {
10
- rt._ensureChannel(ch);
9
+ for (const channel of input.declaredChannels ?? []) {
10
+ rt._ensureChannel(channel);
11
11
  }
12
12
  const pluginHost = {
13
13
  entry: rt.entry,
14
14
  options: rt.options,
15
- subscribe: (t) => rt.subscribe(t),
16
- hasPublisher: (t) => rt.hasPublisher(t),
15
+ subscribe: (channelToken) => rt.subscribe(channelToken),
16
+ hasPublisher: (channelToken) => rt.hasPublisher(channelToken),
17
17
  elements: rt.elements,
18
- defer: (p) => rt.defer(p)
18
+ defer: (deferredPromise) => rt.defer(deferredPromise)
19
19
  };
20
20
  const pluginSetupValues = new Map();
21
21
  for (const plugin of input.plugins ?? []) {
22
- const v = await plugin.setup(pluginHost);
23
- if (typeof v !== "undefined") {
24
- pluginSetupValues.set(plugin, v);
22
+ const setupValue = await plugin.setup(pluginHost);
23
+ if (typeof setupValue !== "undefined") {
24
+ pluginSetupValues.set(plugin, setupValue);
25
25
  }
26
26
  }
27
- const mergePatch = (_ctx, patch) => {
28
- return mergePatchIntoFreshContext(patch);
29
- };
27
+ const mergePatch = (_ctx, patch) => mergePatchIntoFreshContext(patch);
30
28
  let ctx = { value: {} };
31
29
  let result;
32
30
  try {
@@ -42,13 +40,13 @@ export const runCapture = async (input) => {
42
40
  let pluginContributedValue = {};
43
41
  if (boundPlugins.length > 0) {
44
42
  const pluginResults = await Promise.allSettled(boundPlugins
45
- .filter((p) => typeof p.contribute === "function")
46
- .map(async (p) => p.contribute({ value: ctx.value, setupValue: pluginSetupValues.get(p) }, rt)));
47
- for (const r of pluginResults) {
48
- if (r.status !== "fulfilled") {
43
+ .filter((pluginBinding) => typeof pluginBinding.contribute === "function")
44
+ .map(async (pluginBinding) => pluginBinding.contribute({ value: ctx.value, setupValue: pluginSetupValues.get(pluginBinding) }, rt)));
45
+ for (const pluginResult of pluginResults) {
46
+ if (pluginResult.status !== "fulfilled") {
49
47
  continue;
50
48
  }
51
- const patch = r.value;
49
+ const patch = pluginResult.value;
52
50
  if (!patch || typeof patch !== "object") {
53
51
  continue;
54
52
  }
@@ -1,4 +1,4 @@
1
- import type { CompletionStrategy, ContentStore, PathResolver, ResourceFilter } from "../types.js";
1
+ import type { CompletionStrategy, ContentStore, PagePocketOptions, PathResolver, ResourceFilter } from "../types.js";
2
2
  export type EntryInfo = {
3
3
  kind: "url";
4
4
  url: string;
@@ -36,4 +36,4 @@ export interface CaptureOptions {
36
36
  maxResources?: number;
37
37
  };
38
38
  }
39
- export type PagePocketOptions = import("../types.js").PagePocketOptions;
39
+ export type { PagePocketOptions };
package/dist/utils.js CHANGED
@@ -4,8 +4,8 @@ const FNV_PRIME = 0x01000193;
4
4
  export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5
5
  export const hashString = (value) => {
6
6
  let hash = FNV_OFFSET;
7
- for (let i = 0; i < value.length; i += 1) {
8
- hash ^= value.charCodeAt(i);
7
+ for (let characterIndex = 0; characterIndex < value.length; characterIndex += 1) {
8
+ hash ^= value.charCodeAt(characterIndex);
9
9
  hash = (hash * FNV_PRIME) >>> 0;
10
10
  }
11
11
  return hash.toString(16).padStart(8, "0");
@@ -24,9 +24,7 @@ export const sanitizePosixPath = (value) => {
24
24
  }
25
25
  return clean.join("/");
26
26
  };
27
- const getGlobalBuffer = () => {
28
- return globalThis.Buffer;
29
- };
27
+ const getGlobalBuffer = () => globalThis.Buffer;
30
28
  export const bytesToBase64 = (bytes) => {
31
29
  const BufferCtor = getGlobalBuffer();
32
30
  if (BufferCtor) {
@@ -34,8 +32,8 @@ export const bytesToBase64 = (bytes) => {
34
32
  }
35
33
  let binary = "";
36
34
  const chunkSize = 0x8000;
37
- for (let i = 0; i < bytes.length; i += chunkSize) {
38
- const chunk = bytes.subarray(i, i + chunkSize);
35
+ for (let chunkStart = 0; chunkStart < bytes.length; chunkStart += chunkSize) {
36
+ const chunk = bytes.subarray(chunkStart, chunkStart + chunkSize);
39
37
  binary += String.fromCharCode(...chunk);
40
38
  }
41
39
  return btoa(binary);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pagepocket/lib",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "Library for rewriting HTML snapshots and inlining local resources.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,9 +20,9 @@
20
20
  "dependencies": {
21
21
  "cheerio": "^1.0.0-rc.12",
22
22
  "domhandler": "^5.0.3",
23
- "@pagepocket/contracts": "0.11.0",
24
- "@pagepocket/uni-fs": "0.11.0",
25
- "@pagepocket/shared": "0.11.0"
23
+ "@pagepocket/contracts": "0.12.0",
24
+ "@pagepocket/uni-fs": "0.12.0",
25
+ "@pagepocket/shared": "0.12.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@playwright/test": "^1.50.1",