Skip to content

Commit

Permalink
Upstream some changes from the REPL (#7208)
Browse files Browse the repository at this point in the history
  • Loading branch information
mischnic committed Dec 8, 2021
1 parent 1e40346 commit 4f0d297
Show file tree
Hide file tree
Showing 29 changed files with 262 additions and 46 deletions.
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

0 comments on commit 4f0d297

Please sign in to comment.