Skip to content

Commit 951f476

Browse files
domoritzp42-ai[bot]
authored andcommitted
ARROW-12704: [JS] Support and use optional chaining
Optional chaining makes the code more concise and easier to reason about. Needs a fork of esm because of standard-things/esm#866. Closes apache#10278 from domoritz/modern-js Lead-authored-by: Dominik Moritz <domoritz@gmail.com> Co-authored-by: p42-ai[bot] <72252241+p42-ai[bot]@users.noreply.github.com> Signed-off-by: Sutou Kouhei <kou@clear-code.com>
1 parent 300e985 commit 951f476

21 files changed

+92
-99
lines changed

js/bin/integration.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const exists = async (p) => {
6363
}
6464
})()
6565
.then((x) => +x || 0, (e) => {
66-
e && process.stderr.write(`${e && e.stack || e}\n`);
66+
e && process.stderr.write(`${e?.stack || e}\n`);
6767
return process.exitCode || 1;
6868
}).then((code) => process.exit(code));
6969

@@ -141,7 +141,7 @@ function validateReaderIntegration(jsonData, arrowBuffer) {
141141
for (const [jsonRecordBatch, binaryRecordBatch] of zip(jsonReader, binaryReader)) {
142142
compareTableIsh(jsonRecordBatch, binaryRecordBatch);
143143
}
144-
} catch (e) { throw new Error(`${msg}: fail \n ${e && e.stack || e}`); }
144+
} catch (e) { throw new Error(`${msg}: fail \n ${e?.stack || e}`); }
145145
process.stdout.write(`${msg}: pass\n`);
146146
}
147147

@@ -151,7 +151,7 @@ function validateTableFromBuffersIntegration(jsonData, arrowBuffer) {
151151
const jsonTable = Table.from(jsonData);
152152
const binaryTable = Table.from(arrowBuffer);
153153
compareTableIsh(jsonTable, binaryTable);
154-
} catch (e) { throw new Error(`${msg}: fail \n ${e && e.stack || e}`); }
154+
} catch (e) { throw new Error(`${msg}: fail \n ${e?.stack || e}`); }
155155
process.stdout.write(`${msg}: pass\n`);
156156
}
157157

@@ -164,7 +164,7 @@ function validateTableToBuffersIntegration(srcFormat, arrowFormat) {
164164
const srcTable = Table.from(srcFormat === `json` ? jsonData : arrowBuffer);
165165
const dstTable = Table.from(srcTable.serialize(`binary`, arrowFormat === `stream`));
166166
compareTableIsh(dstTable, refTable);
167-
} catch (e) { throw new Error(`${msg}: fail \n ${e && e.stack || e}`); }
167+
} catch (e) { throw new Error(`${msg}: fail \n ${e?.stack || e}`); }
168168
process.stdout.write(`${msg}: pass\n`);
169169
};
170170
}

js/gulp/closure-task.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const closureTask = ((cache) => memoizeTask(cache, async function closure(target
5050
const exportedImports = publicModulePaths(srcAbsolute).reduce((entries, publicModulePath) => [
5151
...entries, {
5252
publicModulePath,
53-
exports_: getPublicExportedNames(esmRequire(publicModulePath, { warnings: false }))
53+
exports_: getPublicExportedNames(esmRequire(publicModulePath))
5454
}
5555
], []);
5656

js/gulp/minify-task.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const {
1919
targetDir,
2020
mainExport,
2121
UMDSourceTargets,
22-
terserLanguageNames,
2322
shouldRunInChildProcess,
2423
spawnGulpCommandInChildProcess,
2524
} = require('./util');
@@ -64,7 +63,7 @@ const minifyTask = ((cache, commonConfig) => memoizeTask(cache, function minifyJ
6463
minimizer: [
6564
new TerserPlugin({
6665
terserOptions: {
67-
ecma: terserLanguageNames[target],
66+
ecma: target,
6867
output: { comments: false },
6968
compress: { unsafe: true }
7069
},

js/gulp/test-task.js

-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ const ARROW_JAVA_DIR = process.env.ARROW_JAVA_DIR || path.join(ARROW_HOME, 'java
7373
const CPP_EXE_PATH = process.env.ARROW_CPP_EXE_PATH || path.join(ARROW_HOME, 'cpp/build/debug');
7474
const ARROW_INTEGRATION_DIR = process.env.ARROW_INTEGRATION_DIR || path.join(ARROW_HOME, 'integration');
7575
const CPP_JSON_TO_ARROW = path.join(CPP_EXE_PATH, 'arrow-json-integration-test');
76-
const CPP_STREAM_TO_FILE = path.join(CPP_EXE_PATH, 'arrow-stream-to-file');
7776
const CPP_FILE_TO_STREAM = path.join(CPP_EXE_PATH, 'arrow-file-to-stream');
7877

7978
const testFilesDir = path.join(ARROW_HOME, 'js/test/data');

js/gulp/util.js

+3-7
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ const gCCLanguageNames = {
6161
es2015: `ECMASCRIPT_2015`,
6262
es2016: `ECMASCRIPT_2016`,
6363
es2017: `ECMASCRIPT_2017`,
64+
es2018: `ECMASCRIPT_2018`,
65+
es2019: `ECMASCRIPT_2019`,
6466
esnext: `ECMASCRIPT_NEXT`
6567
};
6668

@@ -72,12 +74,6 @@ const UMDSourceTargets = {
7274
esnext: `esnext`
7375
};
7476

75-
const terserLanguageNames = {
76-
es5: 5, es2015: 6,
77-
es2016: 7, es2017: 8,
78-
esnext: 8 // <--- ?
79-
};
80-
8177
// ES7+ keywords Terser shouldn't mangle
8278
// Hardcoded here since some are from ES7+, others are
8379
// only defined in interfaces, so difficult to get by reflection.
@@ -211,7 +207,7 @@ module.exports = {
211207
mainExport, npmPkgName, npmOrgName, metadataFiles, packageJSONFields,
212208

213209
knownTargets, knownModules, tasksToSkipPerTargetOrFormat,
214-
gCCLanguageNames, UMDSourceTargets, terserLanguageNames,
210+
gCCLanguageNames, UMDSourceTargets,
215211

216212
taskName, packageName, tsconfigName, targetDir, combinations, observableFromStreams,
217213
ESKeywords, publicModulePaths, esmRequire, shouldRunInChildProcess, spawnGulpCommandInChildProcess

js/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@
7676
"del-cli": "3.0.1",
7777
"eslint": "^7.24.0",
7878
"eslint-plugin-jest": "^24.3.5",
79-
"esm": "3.2.25",
79+
"esm": "https://github.com/jsg2021/esm/releases/download/v3.x.x-pr883/esm-3.x.x-pr883.tgz",
8080
"glob": "7.1.4",
81-
"google-closure-compiler": "20210406.0.0",
81+
"google-closure-compiler": "20210505.0.0",
8282
"gulp": "4.0.2",
8383
"gulp-json-transform": "0.4.7",
8484
"gulp-rename": "2.0.0",

js/src/bin/arrow2csv.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ type ToStringState = {
6767
})()
6868
.then((x) => +x || 0, (err) => {
6969
if (err) {
70-
console.error(`${err && err.stack || err}`);
70+
console.error(`${err?.stack || err}`);
7171
}
7272
return process.exitCode || 1;
7373
}).then((code) => process.exit(code));
@@ -147,7 +147,7 @@ function batchesToString(state: ToStringState, schema: Schema) {
147147
},
148148
transform(batch: RecordBatch, _enc: string, cb: (error?: Error, data?: any) => void) {
149149

150-
batch = !(state.schema && state.schema.length) ? batch : batch.select(...state.schema);
150+
batch = !state.schema?.length ? batch : batch.select(...state.schema);
151151

152152
if (state.closed) { return cb(undefined, null); }
153153

js/src/io/node/iterable.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class IterableReadable<T extends Uint8Array | any> extends Readable {
5454
const it = this._iterator;
5555
let fn: any;
5656
it && (fn = e != null && it.throw || it.return);
57-
fn && fn.call(it, e);
57+
fn?.call(it, e);
5858
cb && cb(null);
5959
}
6060
private _pull(size: number, it: SourceIterator<T>) {
@@ -66,7 +66,7 @@ class IterableReadable<T extends Uint8Array | any> extends Readable {
6666
}
6767
if (!this.push(r.value) || size <= 0) { break; }
6868
}
69-
if ((r && r.done || !this.readable) && (this.push(null) || true)) {
69+
if ((r?.done || !this.readable) && (this.push(null) || true)) {
7070
it.return && it.return();
7171
}
7272
return !this.readable;
@@ -94,7 +94,7 @@ class AsyncIterableReadable<T extends Uint8Array | any> extends Readable {
9494
const it = this._iterator;
9595
let fn: any;
9696
it && (fn = e != null && it.throw || it.return);
97-
fn && fn.call(it, e).then(() => cb && cb(null)) || (cb && cb(null));
97+
fn?.call(it, e).then(() => cb && cb(null)) || (cb && cb(null));
9898
}
9999
private async _pull(size: number, it: AsyncSourceIterator<T>) {
100100
const bm = this._bytesMode;
@@ -105,7 +105,7 @@ class AsyncIterableReadable<T extends Uint8Array | any> extends Readable {
105105
}
106106
if (!this.push(r.value) || size <= 0) { break; }
107107
}
108-
if ((r && r.done || !this.readable) && (this.push(null) || true)) {
108+
if ((r?.done || !this.readable) && (this.push(null) || true)) {
109109
it.return && it.return();
110110
}
111111
return !this.readable;

js/src/io/node/reader.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ class RecordBatchReaderDuplex<T extends { [key: string]: DataType } = any> exten
4444
}
4545
_final(cb?: CB) {
4646
const aq = this._asyncQueue;
47-
aq && aq.close();
47+
aq?.close();
4848
cb && cb();
4949
}
5050
_write(x: any, _: string, cb: CB) {
5151
const aq = this._asyncQueue;
52-
aq && aq.write(x);
52+
aq?.write(x);
5353
cb && cb();
5454
return true;
5555
}
@@ -77,7 +77,7 @@ class RecordBatchReaderDuplex<T extends { [key: string]: DataType } = any> exten
7777
while (this.readable && !(r = await reader.next()).done) {
7878
if (!this.push(r.value) || (size != null && --size <= 0)) { break; }
7979
}
80-
if (!this.readable || (r && r.done && (reader.autoDestroy || (await reader.reset().open()).closed))) {
80+
if (!this.readable || (r?.done && (reader.autoDestroy || (await reader.reset().open()).closed))) {
8181
this.push(null);
8282
await reader.cancel();
8383
}

js/src/io/node/writer.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ class RecordBatchWriterDuplex<T extends { [key: string]: DataType } = any> exten
4040
}
4141
_final(cb?: CB) {
4242
const writer = this._writer;
43-
writer && writer.close();
43+
writer?.close();
4444
cb && cb();
4545
}
4646
_write(x: any, _: string, cb: CB) {
4747
const writer = this._writer;
48-
writer && writer.write(x);
48+
writer?.write(x);
4949
cb && cb();
5050
return true;
5151
}
@@ -68,7 +68,7 @@ class RecordBatchWriterDuplex<T extends { [key: string]: DataType } = any> exten
6868
}
6969
if (!this.push(r.value) || size <= 0) { break; }
7070
}
71-
if ((r && r.done || !this.readable)) {
71+
if ((r?.done || !this.readable)) {
7272
this.push(null);
7373
await reader.cancel();
7474
}

js/src/io/whatwg/iterable.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ export function toDOMStream<T>(source: Iterable<T> | AsyncIterable<T>, options?:
3636
function iterableAsReadableDOMStream<T>(source: Iterable<T>, options?: ReadableDOMStreamOptions) {
3737

3838
let it: SourceIterator<T> | null = null;
39-
const bm = (options && options.type === 'bytes') || false;
40-
const hwm = options && options.highWaterMark || (2 ** 24);
39+
const bm = (options?.type === 'bytes') || false;
40+
const hwm = options?.highWaterMark || (2 ** 24);
4141

4242
return new ReadableStream<T>({
4343
...options as any,
4444
start(controller) { next(controller, it || (it = source[Symbol.iterator]() as SourceIterator<T>)); },
4545
pull(controller) { it ? (next(controller, it)) : controller.close(); },
46-
cancel() { (it && (it.return && it.return()) || true) && (it = null); }
46+
cancel() { (it?.return && it.return() || true) && (it = null); }
4747
}, { highWaterMark: bm ? hwm : undefined, ...options });
4848

4949
function next(controller: ReadableStreamDefaultController<T>, it: SourceIterator<T>) {
@@ -66,14 +66,14 @@ function iterableAsReadableDOMStream<T>(source: Iterable<T>, options?: ReadableD
6666
function asyncIterableAsReadableDOMStream<T>(source: AsyncIterable<T>, options?: ReadableDOMStreamOptions) {
6767

6868
let it: AsyncSourceIterator<T> | null = null;
69-
const bm = (options && options.type === 'bytes') || false;
70-
const hwm = options && options.highWaterMark || (2 ** 24);
69+
const bm = (options?.type === 'bytes') || false;
70+
const hwm = options?.highWaterMark || (2 ** 24);
7171

7272
return new ReadableStream<T>({
7373
...options as any,
7474
async start(controller) { await next(controller, it || (it = source[Symbol.asyncIterator]() as AsyncSourceIterator<T>)); },
7575
async pull(controller) { it ? (await next(controller, it)) : controller.close(); },
76-
async cancel() { (it && (it.return && await it.return()) || true) && (it = null); },
76+
async cancel() { (it?.return && await it.return() || true) && (it = null); },
7777
}, { highWaterMark: bm ? hwm : undefined, ...options });
7878

7979
async function next(controller: ReadableStreamDefaultController<T>, it: AsyncSourceIterator<T>) {

js/src/ipc/message.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export class MessageReader implements IterableIterator<Message> {
7272
public readSchema(throwIfNull = false) {
7373
const type = MessageHeader.Schema;
7474
const message = this.readMessage(type);
75-
const schema = message && message.header();
75+
const schema = message?.header();
7676
if (throwIfNull && !schema) {
7777
throw new Error(nullMessage(type));
7878
}
@@ -81,7 +81,7 @@ export class MessageReader implements IterableIterator<Message> {
8181
protected readMetadataLength(): IteratorResult<number> {
8282
const buf = this.source.read(PADDING);
8383
const bb = buf && new ByteBuffer(buf);
84-
const len = bb && bb.readInt32(0) || 0;
84+
const len = bb?.readInt32(0) || 0;
8585
return { done: len === 0, value: len };
8686
}
8787
protected readMetadata(metadataLength: number): IteratorResult<Message> {
@@ -141,7 +141,7 @@ export class AsyncMessageReader implements AsyncIterableIterator<Message> {
141141
public async readSchema(throwIfNull = false) {
142142
const type = MessageHeader.Schema;
143143
const message = await this.readMessage(type);
144-
const schema = message && message.header();
144+
const schema = message?.header();
145145
if (throwIfNull && !schema) {
146146
throw new Error(nullMessage(type));
147147
}
@@ -150,7 +150,7 @@ export class AsyncMessageReader implements AsyncIterableIterator<Message> {
150150
protected async readMetadataLength(): Promise<IteratorResult<number>> {
151151
const buf = await this.source.read(PADDING);
152152
const bb = buf && new ByteBuffer(buf);
153-
const len = bb && bb.readInt32(0) || 0;
153+
const len = bb?.readInt32(0) || 0;
154154
return { done: len === 0, value: len };
155155
}
156156
protected async readMetadata(metadataLength: number): Promise<IteratorResult<Message>> {
@@ -220,7 +220,7 @@ export class JSONMessageReader extends MessageReader {
220220
public readSchema() {
221221
const type = MessageHeader.Schema;
222222
const message = this.readMessage(type);
223-
const schema = message && message.header();
223+
const schema = message?.header();
224224
if (!message || !schema) {
225225
throw new Error(nullMessage(type));
226226
}

js/src/ipc/reader.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ class RecordBatchFileReaderImpl<T extends { [key: string]: DataType } = any> ext
547547
const block = this._footer && this._footer.getRecordBatch(index);
548548
if (block && this._handle.seek(block.offset)) {
549549
const message = this._reader.readMessage(MessageHeader.RecordBatch);
550-
if (message && message.isRecordBatch()) {
550+
if (message?.isRecordBatch()) {
551551
const header = message.header();
552552
const buffer = this._reader.readMessageBody(message.bodyLength);
553553
const recordBatch = this._loadRecordBatch(header, buffer);
@@ -560,7 +560,7 @@ class RecordBatchFileReaderImpl<T extends { [key: string]: DataType } = any> ext
560560
const block = this._footer && this._footer.getDictionaryBatch(index);
561561
if (block && this._handle.seek(block.offset)) {
562562
const message = this._reader.readMessage(MessageHeader.DictionaryBatch);
563-
if (message && message.isDictionaryBatch()) {
563+
if (message?.isDictionaryBatch()) {
564564
const header = message.header();
565565
const buffer = this._reader.readMessageBody(message.bodyLength);
566566
const vector = this._loadDictionaryBatch(header, buffer);
@@ -621,7 +621,7 @@ class AsyncRecordBatchFileReaderImpl<T extends { [key: string]: DataType } = any
621621
const block = this._footer && this._footer.getRecordBatch(index);
622622
if (block && (await this._handle.seek(block.offset))) {
623623
const message = await this._reader.readMessage(MessageHeader.RecordBatch);
624-
if (message && message.isRecordBatch()) {
624+
if (message?.isRecordBatch()) {
625625
const header = message.header();
626626
const buffer = await this._reader.readMessageBody(message.bodyLength);
627627
const recordBatch = this._loadRecordBatch(header, buffer);
@@ -634,7 +634,7 @@ class AsyncRecordBatchFileReaderImpl<T extends { [key: string]: DataType } = any
634634
const block = this._footer && this._footer.getDictionaryBatch(index);
635635
if (block && (await this._handle.seek(block.offset))) {
636636
const message = await this._reader.readMessage(MessageHeader.DictionaryBatch);
637-
if (message && message.isDictionaryBatch()) {
637+
if (message?.isDictionaryBatch()) {
638638
const header = message.header();
639639
const buffer = await this._reader.readMessageBody(message.bodyLength);
640640
const vector = this._loadDictionaryBatch(header, buffer);

js/src/table.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export class Table<T extends { [key: string]: DataType } = any>
185185

186186
const chunks = selectArgs<RecordBatch<T>>(RecordBatch, args);
187187

188-
if (!schema && !(schema = chunks[0] && chunks[0].schema)) {
188+
if (!schema && !(schema = chunks[0]?.schema)) {
189189
throw new TypeError('Table must be initialized with a Schema or at least one RecordBatch');
190190
}
191191

0 commit comments

Comments
 (0)