Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream some changes from the REPL #7208

Merged
merged 11 commits into from Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 24 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions packages/core/cache/package.json
Expand Up @@ -30,5 +30,12 @@
},
"peerDependencies": {
"@parcel/core": "^2.0.0"
},
"devDependencies": {
"idb": "^5.0.8"
},
"browser": {
"./src/IDBCache.js": "./src/IDBCache.browser.js",
"./src/LMDBCache.js": false
}
}
120 changes: 120 additions & 0 deletions packages/core/cache/src/IDBCache.browser.js
@@ -0,0 +1,120 @@
// @flow strict-local
import type {Cache} from './types';

import {Readable} from 'stream';
import {serialize, deserialize, registerSerializableClass} from '@parcel/core';
import {bufferStream} from '@parcel/utils';
// $FlowFixMe[untyped-import]
import packageJson from '../package.json';
// $FlowFixMe[untyped-import]
import {openDB} from 'idb';

const STORE_NAME = 'cache';

export class IDBCache implements Cache {
// $FlowFixMe
store: any;

constructor() {
this.store = openDB('REPL-parcel-cache', 1, {
upgrade(db) {
db.createObjectStore(STORE_NAME);
},
blocked() {},
blocking() {},
terminated() {},
});
}

ensure(): Promise<void> {
return Promise.resolve();
}

serialize(): {||} {
return {...null};
}

static deserialize(): IDBCache {
return new IDBCache();
}

has(key: string): Promise<boolean> {
return Promise.resolve(this.store.get(key) != null);
}

async get<T>(key: string): Promise<?T> {
let data = await (await this.store).get(STORE_NAME, key);
if (data == null) {
return null;
}

return Promise.resolve(deserialize(data));
}

async set(key: string, value: mixed): Promise<void> {
await (await this.store).put(STORE_NAME, serialize(value), key);
}

getStream(key: string): Readable {
let dataPromise = this.store
.then(s => s.get(STORE_NAME, key))
.then(d => Buffer.from(d))
.catch(e => e);
const stream = new Readable({
// $FlowFixMe(incompatible-call)
async read() {
let data = await dataPromise;
if (data instanceof Error) {
stream.emit('error', data);
} else {
stream.push(Buffer.from(data));
stream.push(null);
}
},
});

return stream;
}

async setStream(key: string, stream: Readable): Promise<void> {
let buf = await bufferStream(stream);
await (await this.store).put(STORE_NAME, buf, key);
}

async getBlob(key: string): Promise<Buffer> {
let data = await (await this.store).get(STORE_NAME, key);
if (data == null) {
return Promise.reject(new Error(`Key ${key} not found in cache`));
}
return Buffer.from(data.buffer);
}

async setBlob(key: string, contents: Buffer | string): Promise<void> {
let data =
contents instanceof Uint8Array ? contents : Buffer.from(contents);
await (await this.store).put(STORE_NAME, data, key);
}

async getBuffer(key: string): Promise<?Buffer> {
let data = await (await this.store).get(STORE_NAME, key);
if (data == null) {
return null;
}

return Buffer.from(data.buffer);
}

hasLargeBlob(key: string): Promise<boolean> {
return this.has(key);
}

getLargeBlob(key: string): Promise<Buffer> {
return this.getBlob(key);
}

setLargeBlob(key: string, contents: Buffer | string): Promise<void> {
return this.setBlob(key, contents);
}
}

registerSerializableClass(`${packageJson.version}:IDBCache`, IDBCache);
9 changes: 9 additions & 0 deletions packages/core/cache/src/IDBCache.js
@@ -0,0 +1,9 @@
// @flow strict-local
import type {Cache} from './types';

// $FlowFixMe
export class IDBCache implements Cache {
constructor() {
throw new Error('IDBCache is only supported in the browser');
}
}
1 change: 1 addition & 0 deletions packages/core/cache/src/index.js
Expand Up @@ -2,3 +2,4 @@
export type {Cache} from './types';
export * from './LMDBCache';
export * from './FSCache';
export * from './IDBCache';
4 changes: 4 additions & 0 deletions packages/core/core/package.json
Expand Up @@ -45,12 +45,16 @@
"dotenv-expand": "^5.1.0",
"json-source-map": "^0.6.1",
"json5": "^1.0.1",
"msgpackr": "^1.5.1",
"micromatch": "^4.0.2",
"nullthrows": "^1.1.1",
"semver": "^5.7.1"
},
"devDependencies": {
"graphviz": "^0.0.9",
"tempy": "^0.2.1"
},
"browser": {
"./src/serializerCore.js": "./src/serializerCore.browser.js"
}
}
7 changes: 4 additions & 3 deletions packages/core/core/src/PackagerRunner.js
Expand Up @@ -648,10 +648,11 @@ export default class PackagerRunner {
);
hash = h.finish();
} else if (typeof contents === 'string') {
size = Buffer.byteLength(contents);
hash = hashString(contents);
let buffer = Buffer.from(contents);
size = buffer.byteLength;
hash = hashBuffer(buffer);
hashReferences = contents.match(HASH_REF_REGEX) ?? [];
await this.options.cache.setBlob(cacheKeys.content, contents);
await this.options.cache.setBlob(cacheKeys.content, buffer);
} else {
size = contents.length;
hash = hashBuffer(contents);
Expand Down
10 changes: 4 additions & 6 deletions packages/core/core/src/serializer.js
@@ -1,11 +1,8 @@
// @flow
import v8 from 'v8';
import {createBuildCache} from './buildCache';
import {serializeRaw, deserializeRaw} from './serializerCore';

// $FlowFixMe - Flow doesn't know about this method yet
export let serializeRaw = v8.serialize;
// $FlowFixMe - Flow doesn't know about this method yet
export let deserializeRaw = v8.deserialize;
export {serializeRaw, deserializeRaw} from './serializerCore';

const nameToCtor: Map<string, Class<any>> = new Map();
const ctorToName: Map<Class<any>, string> = new Map();
Expand Down Expand Up @@ -55,7 +52,8 @@ function shallowCopy(object: any) {
function isBuffer(object) {
return (
object.buffer instanceof ArrayBuffer ||
object.buffer instanceof SharedArrayBuffer
(typeof SharedArrayBuffer !== 'undefined' &&
object.buffer instanceof SharedArrayBuffer)
);
}

Expand Down
8 changes: 8 additions & 0 deletions packages/core/core/src/serializerCore.browser.js
@@ -0,0 +1,8 @@
// @flow
import {Buffer} from 'buffer';
import * as msgpackr from 'msgpackr';

let encoder = new msgpackr.Encoder({structuredClone: true});

export let serializeRaw: any => Buffer = v => Buffer.from(encoder.encode(v));
export let deserializeRaw: Buffer => any = v => encoder.decode(v);
7 changes: 7 additions & 0 deletions packages/core/core/src/serializerCore.js
@@ -0,0 +1,7 @@
// @flow
import v8 from 'v8';

// $FlowFixMe - Flow doesn't know about this method yet
export let serializeRaw: any => Buffer = v8.serialize;
// $FlowFixMe - Flow doesn't know about this method yet
export let deserializeRaw: Buffer => any = v8.deserialize;
3 changes: 3 additions & 0 deletions packages/core/fs/package.json
Expand Up @@ -40,5 +40,8 @@
},
"peerDependencies": {
"@parcel/core": "^2.0.0"
},
"browser": {
"./src/NodeFS.js": "./src/NodeFS.browser.js"
}
}
8 changes: 3 additions & 5 deletions packages/core/fs/src/MemoryFS.js
Expand Up @@ -11,6 +11,7 @@ import type {
import path from 'path';
import {Readable, Writable} from 'stream';
import {registerSerializableClass} from '@parcel/core';
import {SharedBuffer} from '@parcel/utils';
import packageJSON from '../package.json';
import WorkerFarm, {Handle} from '@parcel/workers';
import nullthrows from 'nullthrows';
Expand Down Expand Up @@ -904,15 +905,12 @@ class Directory extends Entry {
}

function makeShared(contents: Buffer | string): Buffer {
if (
typeof contents !== 'string' &&
contents.buffer instanceof SharedArrayBuffer
) {
if (typeof contents !== 'string' && contents.buffer instanceof SharedBuffer) {
return contents;
}

let length = Buffer.byteLength(contents);
let shared = new SharedArrayBuffer(length);
let shared = new SharedBuffer(length);
let buffer = Buffer.from(shared);
if (typeof contents === 'string') {
buffer.write(contents);
Expand Down
9 changes: 9 additions & 0 deletions packages/core/fs/src/NodeFS.browser.js
@@ -0,0 +1,9 @@
// @flow
import type {FileSystem} from './types';

// $FlowFixMe[prop-missing] handled by the throwing constructor
export class NodeFS implements FileSystem {
constructor() {
throw new Error("NodeFS isn't available in the browser");
}
}
5 changes: 2 additions & 3 deletions packages/core/graph/src/AdjacencyList.js
@@ -1,6 +1,7 @@
// @flow
import assert from 'assert';
import nullthrows from 'nullthrows';
import {SharedBuffer} from '@parcel/utils';
import {fromNodeId, toNodeId} from './types';
import {ALL_EDGE_TYPES, type NullEdgeType, type AllEdgeTypes} from './Graph';
import type {NodeId} from './types';
Expand Down Expand Up @@ -610,9 +611,7 @@ export class SharedTypeMap<TItemType, THash, TAddress: number>
let CAPACITY = SharedTypeMap.#CAPACITY;
// $FlowFixMe[incompatible-call]
this.data = new Uint32Array(
new SharedArrayBuffer(
this.getLength(capacityOrData) * BYTES_PER_ELEMENT,
),
new SharedBuffer(this.getLength(capacityOrData) * BYTES_PER_ELEMENT),
);
this.data[CAPACITY] = capacityOrData;
} else {
Expand Down
5 changes: 5 additions & 0 deletions packages/core/package-manager/package.json
Expand Up @@ -39,5 +39,10 @@
},
"peerDependencies": {
"@parcel/core": "^2.0.0"
},
"browser": {
"./src/Npm.js": false,
"./src/Pnpm.js": false,
"./src/Yarn.js": false
}
}
5 changes: 5 additions & 0 deletions packages/core/utils/package.json
Expand Up @@ -45,5 +45,10 @@
"devDependencies": {
"@babel/plugin-transform-flow-strip-types": "^7.2.0",
"random-int": "^1.0.0"
},
"browser": {
"./src/generateCertificate.js": false,
"./src/http-server.js": false,
"./src/openInBrowser.js": false
}
}
3 changes: 0 additions & 3 deletions packages/core/utils/src/.babelrc

This file was deleted.

1 change: 1 addition & 0 deletions packages/core/utils/src/blob.js
Expand Up @@ -2,6 +2,7 @@

import type {Blob} from '@parcel/types';

import {Buffer} from 'buffer';
import {bufferStream} from './';
import {Readable} from 'stream';

Expand Down