GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — repl: keep entries added while history file is loading · nodejs/node@bb499c3

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • lib/internal/repl
    • history.js
  • test/parallel
    • test-repl-history-load-preserves-pending-entries.js
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎lib/internal/repl/history.js‎

Copy file name to clipboardExpand all lines: lib/internal/repl/history.js
+15-3Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const {
44
ArrayPrototypeIndexOf,
55
ArrayPrototypeJoin,
66
ArrayPrototypePop,
7+
ArrayPrototypePushApply,
78
ArrayPrototypeShift,
89
ArrayPrototypeSplice,
910
ArrayPrototypeUnshift,
@@ -302,10 +303,21 @@ class ReplHistory {
302303
return this[kHandleHistoryInitError](err, onReadyCallback);
303304
}
304305

305-
if (data) {
306-
this[kHistory] = RegExpPrototypeSymbolSplit(/\r?\n+/, data, this[kSize]);
306+
const loadedHistory = data ?
307+
RegExpPrototypeSymbolSplit(/\r?\n+/, data, this[kSize]) :
308+
[];
309+
310+
// Lines can be evaluated while the history file is still being read,
311+
// e.g. when the input stream does not support pausing. Such entries
312+
// are already in the in-memory history (newest first), so append the
313+
// persisted entries to them instead of discarding them.
314+
if (this[kHistory].length > 0) {
315+
ArrayPrototypePushApply(this[kHistory], loadedHistory);
316+
if (this[kHistory].length > this[kSize]) {
317+
ArrayPrototypeSplice(this[kHistory], this[kSize]);
318+
}
307319
} else {
308-
this[kHistory] = [];
320+
this[kHistory] = loadedHistory;
309321
}
310322

311323
validateArray(this[kHistory], 'history');
Collapse file

‎test/parallel/test-repl-history-load-preserves-pending-entries.js‎

Copy file name to clipboard
+64Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
'use strict';
2+
3+
// Lines can be evaluated while the history file is still being loaded
4+
// asynchronously by `setupHistory()`, e.g. when the input stream does not
5+
// support pausing. Entries added to the in-memory history in the meantime
6+
// must not be discarded once the file load completes.
7+
// Refs: https://github.com/nodejs/node/issues/64508
8+
9+
const common = require('../common');
10+
const assert = require('assert');
11+
const fs = require('fs');
12+
const stream = require('stream');
13+
const repl = require('repl');
14+
15+
if (process.env.TERM === 'dumb') {
16+
common.skip('skipping - dumb terminal');
17+
}
18+
19+
common.skipIfInspectorDisabled();
20+
21+
const tmpdir = require('../common/tmpdir');
22+
tmpdir.refresh();
23+
24+
const historyPath = tmpdir.resolve('.repl_history');
25+
fs.writeFileSync(historyPath, 'persisted entry');
26+
27+
// An input stream that, unlike a TTY, does not buffer data while paused.
28+
class FakeInput extends stream.Stream {
29+
resume() {}
30+
pause() {}
31+
}
32+
FakeInput.prototype.readable = true;
33+
34+
const input = new FakeInput();
35+
const output = new stream.Writable({
36+
write(chunk, encoding, callback) {
37+
callback();
38+
},
39+
});
40+
41+
const r = repl.start({
42+
input,
43+
output,
44+
prompt: '',
45+
terminal: true,
46+
useColors: false,
47+
});
48+
49+
r.setupHistory(historyPath, common.mustSucceed(() => {
50+
// The lines evaluated while the history file was being read must be kept,
51+
// newest first, followed by the persisted entries.
52+
assert.deepStrictEqual(
53+
r.history,
54+
['const b = 2', 'const a = 1', 'persisted entry'],
55+
);
56+
assert.strictEqual(
57+
fs.readFileSync(historyPath, 'utf8'),
58+
'const b = 2\nconst a = 1\npersisted entry',
59+
);
60+
r.close();
61+
}));
62+
63+
// Evaluated synchronously, before the history file has been read.
64+
input.emit('data', 'const a = 1\nconst b = 2\n');

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.