@jsii/kernel 1.65.0 → 1.67.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.
- package/lib/disk-cache/digest-file.d.ts +3 -0
- package/lib/disk-cache/digest-file.js +27 -0
- package/lib/disk-cache/disk-cache.d.ts +27 -0
- package/lib/disk-cache/disk-cache.js +208 -0
- package/lib/disk-cache/index.d.ts +2 -0
- package/lib/disk-cache/index.js +18 -0
- package/lib/kernel.d.ts +6 -0
- package/lib/kernel.js +43 -14
- package/lib/link.d.ts +9 -0
- package/lib/link.js +30 -0
- package/lib/objects.d.ts +1 -1
- package/lib/objects.js +8 -5
- package/lib/tar-cache/default-cache-root.d.ts +2 -0
- package/lib/tar-cache/default-cache-root.js +26 -0
- package/lib/tar-cache/index.d.ts +33 -0
- package/lib/tar-cache/index.js +77 -0
- package/package.json +7 -5
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.digestFile = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const ALGORITHM = 'sha256';
|
|
7
|
+
function digestFile(path, ...comments) {
|
|
8
|
+
const hash = (0, crypto_1.createHash)(ALGORITHM);
|
|
9
|
+
const buffer = Buffer.alloc(16384);
|
|
10
|
+
const fd = (0, fs_1.openSync)(path, 'r');
|
|
11
|
+
try {
|
|
12
|
+
let bytesRead = 0;
|
|
13
|
+
while ((bytesRead = (0, fs_1.readSync)(fd, buffer)) > 0) {
|
|
14
|
+
hash.update(buffer.slice(0, bytesRead));
|
|
15
|
+
}
|
|
16
|
+
for (const comment of comments) {
|
|
17
|
+
hash.update('\0');
|
|
18
|
+
hash.update(comment);
|
|
19
|
+
}
|
|
20
|
+
return hash.digest();
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
(0, fs_1.closeSync)(fd);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.digestFile = digestFile;
|
|
27
|
+
//# sourceMappingURL=digest-file.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export declare class DiskCache {
|
|
3
|
+
#private;
|
|
4
|
+
private static readonly CACHE;
|
|
5
|
+
static inDirectory(path: string): DiskCache;
|
|
6
|
+
private constructor();
|
|
7
|
+
entry(...key: readonly string[]): Entry;
|
|
8
|
+
entryFor(path: string, ...comments: readonly string[]): Entry;
|
|
9
|
+
pruneExpiredEntries(): void;
|
|
10
|
+
private entries;
|
|
11
|
+
}
|
|
12
|
+
export declare class Entry {
|
|
13
|
+
readonly path: string;
|
|
14
|
+
constructor(path: string);
|
|
15
|
+
get atime(): Date;
|
|
16
|
+
get pathExists(): boolean;
|
|
17
|
+
private get lockFile();
|
|
18
|
+
private get markerFile();
|
|
19
|
+
lock<T>(cb: (entry: LockedEntry) => T): T;
|
|
20
|
+
read(file: string): Buffer | undefined;
|
|
21
|
+
}
|
|
22
|
+
export interface LockedEntry {
|
|
23
|
+
delete(): void;
|
|
24
|
+
write(name: string, data: Buffer): void;
|
|
25
|
+
touch(): void;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=disk-cache.d.ts.map
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _DiskCache_root;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.Entry = exports.DiskCache = void 0;
|
|
16
|
+
const fs_1 = require("fs");
|
|
17
|
+
const lockfile_1 = require("lockfile");
|
|
18
|
+
const path_1 = require("path");
|
|
19
|
+
const digest_file_1 = require("./digest-file");
|
|
20
|
+
const MARKER_FILE_NAME = '.jsii-runtime-package-cache';
|
|
21
|
+
const ONE_DAY_IN_MS = 86400000;
|
|
22
|
+
const PRUNE_AFTER_MILLISECONDS = process.env.JSII_RUNTIME_PACKAGE_CACHE_TTL
|
|
23
|
+
? parseInt(process.env.JSII_RUNTIME_PACKAGE_CACHE_TTL, 10) * ONE_DAY_IN_MS
|
|
24
|
+
: 30 * ONE_DAY_IN_MS;
|
|
25
|
+
class DiskCache {
|
|
26
|
+
constructor(root) {
|
|
27
|
+
_DiskCache_root.set(this, void 0);
|
|
28
|
+
__classPrivateFieldSet(this, _DiskCache_root, root, "f");
|
|
29
|
+
process.once('beforeExit', () => this.pruneExpiredEntries());
|
|
30
|
+
}
|
|
31
|
+
static inDirectory(path) {
|
|
32
|
+
const didCreate = (0, fs_1.mkdirSync)(path, { recursive: true }) != null;
|
|
33
|
+
if (didCreate && process.platform === 'darwin') {
|
|
34
|
+
// Mark the directories for no iCloud sync, no Spotlight indexing, no TimeMachine backup
|
|
35
|
+
// @see https://michaelbach.de/2019/03/19/MacOS-nosync-noindex-nobackup.html
|
|
36
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(path, '.nobackup'), '');
|
|
37
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(path, '.noindex'), '');
|
|
38
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(path, '.nosync'), '');
|
|
39
|
+
}
|
|
40
|
+
path = (0, fs_1.realpathSync)(path);
|
|
41
|
+
if (!this.CACHE.has(path)) {
|
|
42
|
+
this.CACHE.set(path, new DiskCache(path));
|
|
43
|
+
}
|
|
44
|
+
return this.CACHE.get(path);
|
|
45
|
+
}
|
|
46
|
+
entry(...key) {
|
|
47
|
+
if (key.length === 0) {
|
|
48
|
+
throw new Error(`Cache entry key must contain at least 1 element!`);
|
|
49
|
+
}
|
|
50
|
+
return new Entry((0, path_1.join)(__classPrivateFieldGet(this, _DiskCache_root, "f"), ...key.flatMap((s) => s
|
|
51
|
+
.replace(/[^@a-z0-9_.\\/-]+/g, '_')
|
|
52
|
+
.split(/[\\/]+/)
|
|
53
|
+
.map((ss) => {
|
|
54
|
+
if (ss === '..') {
|
|
55
|
+
throw new Error(`A cache entry key cannot contain a '..' path segment! (${s})`);
|
|
56
|
+
}
|
|
57
|
+
return ss;
|
|
58
|
+
}))));
|
|
59
|
+
}
|
|
60
|
+
entryFor(path, ...comments) {
|
|
61
|
+
const rawDigest = (0, digest_file_1.digestFile)(path, ...comments);
|
|
62
|
+
return this.entry(...comments, rawDigest.toString('hex'));
|
|
63
|
+
}
|
|
64
|
+
pruneExpiredEntries() {
|
|
65
|
+
const cutOff = new Date(Date.now() - PRUNE_AFTER_MILLISECONDS);
|
|
66
|
+
for (const entry of this.entries()) {
|
|
67
|
+
if (entry.atime < cutOff) {
|
|
68
|
+
entry.lock((lockedEntry) => {
|
|
69
|
+
// Check again in case it's been accessed which we waited for the lock...
|
|
70
|
+
if (entry.atime > cutOff) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
lockedEntry.delete();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (const dir of directoriesUnder(__classPrivateFieldGet(this, _DiskCache_root, "f"), true)) {
|
|
78
|
+
if (process.platform === 'darwin') {
|
|
79
|
+
try {
|
|
80
|
+
(0, fs_1.rmSync)((0, path_1.join)(dir, '.DS_Store'), { force: true });
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Ignore errors...
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if ((0, fs_1.readdirSync)(dir).length === 0) {
|
|
87
|
+
try {
|
|
88
|
+
(0, fs_1.rmdirSync)(dir);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Ignore errors, directory may no longer be empty...
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
*entries() {
|
|
97
|
+
yield* inDirectory(__classPrivateFieldGet(this, _DiskCache_root, "f"));
|
|
98
|
+
function* inDirectory(dir) {
|
|
99
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(dir, MARKER_FILE_NAME))) {
|
|
100
|
+
return yield new Entry(dir);
|
|
101
|
+
}
|
|
102
|
+
for (const file of directoriesUnder(dir)) {
|
|
103
|
+
yield* inDirectory(file);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.DiskCache = DiskCache;
|
|
109
|
+
_DiskCache_root = new WeakMap();
|
|
110
|
+
DiskCache.CACHE = new Map();
|
|
111
|
+
class Entry {
|
|
112
|
+
constructor(path) {
|
|
113
|
+
this.path = path;
|
|
114
|
+
}
|
|
115
|
+
get atime() {
|
|
116
|
+
try {
|
|
117
|
+
const stat = (0, fs_1.statSync)(this.markerFile);
|
|
118
|
+
return stat.atime;
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
if (err.code !== 'ENOENT') {
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
return new Date(0);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
get pathExists() {
|
|
128
|
+
return (0, fs_1.existsSync)(this.path);
|
|
129
|
+
}
|
|
130
|
+
get lockFile() {
|
|
131
|
+
return `${this.path}.lock`;
|
|
132
|
+
}
|
|
133
|
+
get markerFile() {
|
|
134
|
+
return (0, path_1.join)(this.path, MARKER_FILE_NAME);
|
|
135
|
+
}
|
|
136
|
+
lock(cb) {
|
|
137
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(this.path), { recursive: true });
|
|
138
|
+
(0, lockfile_1.lockSync)(this.lockFile, { retries: 12, stale: 5000 });
|
|
139
|
+
let disposed = false;
|
|
140
|
+
try {
|
|
141
|
+
return cb({
|
|
142
|
+
delete: () => {
|
|
143
|
+
if (disposed) {
|
|
144
|
+
throw new Error(`Cannot delete ${this.path} once the lock block was returned!`);
|
|
145
|
+
}
|
|
146
|
+
(0, fs_1.rmSync)(this.path, { force: true, recursive: true });
|
|
147
|
+
},
|
|
148
|
+
write: (name, content) => {
|
|
149
|
+
if (disposed) {
|
|
150
|
+
throw new Error(`Cannot write ${(0, path_1.join)(this.path, name)} once the lock block was returned!`);
|
|
151
|
+
}
|
|
152
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)((0, path_1.join)(this.path, name)), { recursive: true });
|
|
153
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(this.path, name), content);
|
|
154
|
+
},
|
|
155
|
+
touch: () => {
|
|
156
|
+
if (disposed) {
|
|
157
|
+
throw new Error(`Cannot touch ${this.path} once the lock block was returned!`);
|
|
158
|
+
}
|
|
159
|
+
if (this.pathExists) {
|
|
160
|
+
if ((0, fs_1.existsSync)(this.markerFile)) {
|
|
161
|
+
const now = new Date();
|
|
162
|
+
(0, fs_1.utimesSync)(this.markerFile, now, now);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
(0, fs_1.writeFileSync)(this.markerFile, '');
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
disposed = true;
|
|
173
|
+
(0, lockfile_1.unlockSync)(this.lockFile);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
read(file) {
|
|
177
|
+
try {
|
|
178
|
+
return (0, fs_1.readFileSync)((0, path_1.join)(this.path, file));
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
if (error.code === 'ENOENT') {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.Entry = Entry;
|
|
189
|
+
function* directoriesUnder(root, recursive = false, ignoreErrors = true) {
|
|
190
|
+
for (const file of (0, fs_1.readdirSync)(root)) {
|
|
191
|
+
const path = (0, path_1.join)(root, file);
|
|
192
|
+
try {
|
|
193
|
+
const stat = (0, fs_1.statSync)(path);
|
|
194
|
+
if (stat.isDirectory()) {
|
|
195
|
+
if (recursive) {
|
|
196
|
+
yield* directoriesUnder(path, recursive, ignoreErrors);
|
|
197
|
+
}
|
|
198
|
+
yield path;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
if (!ignoreErrors) {
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=disk-cache.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./disk-cache"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
package/lib/kernel.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ export declare class Kernel {
|
|
|
5
5
|
* Set to true for verbose debugging.
|
|
6
6
|
*/
|
|
7
7
|
traceEnabled: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Set to true for timing data to be emitted.
|
|
10
|
+
*/
|
|
11
|
+
debugTimingEnabled: boolean;
|
|
8
12
|
private readonly assemblies;
|
|
9
13
|
private readonly objects;
|
|
10
14
|
private readonly cbs;
|
|
@@ -24,6 +28,7 @@ export declare class Kernel {
|
|
|
24
28
|
*/
|
|
25
29
|
constructor(callbackHandler: (callback: api.Callback) => any);
|
|
26
30
|
load(req: api.LoadRequest): api.LoadResponse;
|
|
31
|
+
private _load;
|
|
27
32
|
invokeBinScript(req: api.InvokeScriptRequest): api.InvokeScriptResponse;
|
|
28
33
|
create(req: api.CreateRequest): api.CreateResponse;
|
|
29
34
|
del(req: api.DelRequest): api.DelResponse;
|
|
@@ -67,6 +72,7 @@ export declare class Kernel {
|
|
|
67
72
|
private _fromSandboxValues;
|
|
68
73
|
private _boxUnboxParameters;
|
|
69
74
|
private _debug;
|
|
75
|
+
private _debugTime;
|
|
70
76
|
/**
|
|
71
77
|
* Ensures that `fn` is called and defends against beginning to invoke
|
|
72
78
|
* async methods until fn finishes (successfully or not).
|
package/lib/kernel.js
CHANGED
|
@@ -4,16 +4,18 @@ exports.Kernel = void 0;
|
|
|
4
4
|
const spec = require("@jsii/spec");
|
|
5
5
|
const spec_1 = require("@jsii/spec");
|
|
6
6
|
const cp = require("child_process");
|
|
7
|
+
const fs_1 = require("fs");
|
|
7
8
|
const fs = require("fs-extra");
|
|
8
9
|
const module_1 = require("module");
|
|
9
10
|
const os = require("os");
|
|
10
11
|
const path = require("path");
|
|
11
|
-
const tar = require("tar");
|
|
12
12
|
const api = require("./api");
|
|
13
13
|
const api_1 = require("./api");
|
|
14
|
+
const link_1 = require("./link");
|
|
14
15
|
const objects_1 = require("./objects");
|
|
15
16
|
const onExit = require("./on-exit");
|
|
16
17
|
const wire = require("./serialization");
|
|
18
|
+
const tar = require("./tar-cache");
|
|
17
19
|
class Kernel {
|
|
18
20
|
/**
|
|
19
21
|
* Creates a jsii kernel object.
|
|
@@ -28,6 +30,10 @@ class Kernel {
|
|
|
28
30
|
* Set to true for verbose debugging.
|
|
29
31
|
*/
|
|
30
32
|
this.traceEnabled = false;
|
|
33
|
+
/**
|
|
34
|
+
* Set to true for timing data to be emitted.
|
|
35
|
+
*/
|
|
36
|
+
this.debugTimingEnabled = false;
|
|
31
37
|
this.assemblies = new Map();
|
|
32
38
|
this.objects = new objects_1.ObjectTable(this._typeInfoForFqn.bind(this));
|
|
33
39
|
this.cbs = new Map();
|
|
@@ -36,7 +42,10 @@ class Kernel {
|
|
|
36
42
|
this.nextid = 20000; // incrementing counter for objid, cbid, promiseid
|
|
37
43
|
}
|
|
38
44
|
load(req) {
|
|
39
|
-
|
|
45
|
+
return this._debugTime(() => this._load(req), `load(${JSON.stringify(req, null, 2)})`);
|
|
46
|
+
}
|
|
47
|
+
_load(req) {
|
|
48
|
+
var _a, _b, _c;
|
|
40
49
|
this._debug('load', req);
|
|
41
50
|
if ('assembly' in req) {
|
|
42
51
|
throw new Error('`assembly` field is deprecated for "load", use `name`, `version` and `tarball` instead');
|
|
@@ -61,20 +70,26 @@ class Kernel {
|
|
|
61
70
|
types: Object.keys((_a = assm.metadata.types) !== null && _a !== void 0 ? _a : {}).length,
|
|
62
71
|
};
|
|
63
72
|
}
|
|
64
|
-
// Create the install directory (there may be several path components for @scoped/packages)
|
|
65
|
-
fs.mkdirpSync(packageDir);
|
|
66
73
|
// Force umask to have npm-install-like permissions
|
|
67
74
|
const originalUmask = process.umask(0o022);
|
|
68
75
|
try {
|
|
69
76
|
// untar the archive to its final location
|
|
70
|
-
tar.extract({
|
|
71
|
-
cwd: packageDir,
|
|
72
|
-
file: req.tarball,
|
|
77
|
+
const { path: extractedTo, cache } = this._debugTime(() => tar.extract(req.tarball, {
|
|
73
78
|
strict: true,
|
|
74
79
|
strip: 1,
|
|
75
|
-
sync: true,
|
|
76
80
|
unlink: true,
|
|
77
|
-
});
|
|
81
|
+
}, req.name, req.version), `tar.extract(${req.tarball}) => ${packageDir}`);
|
|
82
|
+
// Create the install directory (there may be several path components for @scoped/packages)
|
|
83
|
+
fs.mkdirSync(path.dirname(packageDir), { recursive: true });
|
|
84
|
+
if (cache != null) {
|
|
85
|
+
this._debug(`Package cache enabled, extraction resulted in a cache ${cache}`);
|
|
86
|
+
// Link the package into place.
|
|
87
|
+
this._debugTime(() => (0, link_1.link)(extractedTo, packageDir), `link(${extractedTo}, ${packageDir})`);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// This is not from cache, so we move it around instead of copying.
|
|
91
|
+
(0, fs_1.renameSync)(extractedTo, packageDir);
|
|
92
|
+
}
|
|
78
93
|
}
|
|
79
94
|
finally {
|
|
80
95
|
// Reset umask to the initial value
|
|
@@ -83,18 +98,18 @@ class Kernel {
|
|
|
83
98
|
// read .jsii metadata from the root of the package
|
|
84
99
|
let assmSpec;
|
|
85
100
|
try {
|
|
86
|
-
assmSpec = (0, spec_1.loadAssemblyFromPath)(packageDir);
|
|
101
|
+
assmSpec = this._debugTime(() => (0, spec_1.loadAssemblyFromPath)(packageDir), `loadAssemblyFromPath(${packageDir})`);
|
|
87
102
|
}
|
|
88
103
|
catch (e) {
|
|
89
104
|
throw new Error(`Error for package tarball ${req.tarball}: ${e.message}`);
|
|
90
105
|
}
|
|
91
106
|
// load the module and capture its closure
|
|
92
|
-
const closure = this.require(packageDir);
|
|
107
|
+
const closure = this._debugTime(() => this.require(packageDir), `require(${packageDir})`);
|
|
93
108
|
const assm = new Assembly(assmSpec, closure);
|
|
94
|
-
this._addAssembly(assm);
|
|
109
|
+
this._debugTime(() => this._addAssembly(assm), `registerAssembly({ name: ${assm.metadata.name}, types: ${Object.keys((_b = assm.metadata.types) !== null && _b !== void 0 ? _b : {}).length} })`);
|
|
95
110
|
return {
|
|
96
111
|
assembly: assmSpec.name,
|
|
97
|
-
types: Object.keys((
|
|
112
|
+
types: Object.keys((_c = assmSpec.types) !== null && _c !== void 0 ? _c : {}).length,
|
|
98
113
|
};
|
|
99
114
|
}
|
|
100
115
|
invokeBinScript(req) {
|
|
@@ -359,7 +374,7 @@ class Kernel {
|
|
|
359
374
|
case spec.TypeKind.Class:
|
|
360
375
|
case spec.TypeKind.Enum:
|
|
361
376
|
const constructor = this._findSymbol(fqn);
|
|
362
|
-
(0, objects_1.tagJsiiConstructor)(constructor, fqn);
|
|
377
|
+
(0, objects_1.tagJsiiConstructor)(constructor, fqn, assm.metadata.version);
|
|
363
378
|
}
|
|
364
379
|
}
|
|
365
380
|
}
|
|
@@ -825,6 +840,20 @@ class Kernel {
|
|
|
825
840
|
console.error('[@jsii/kernel]', ...args);
|
|
826
841
|
}
|
|
827
842
|
}
|
|
843
|
+
_debugTime(cb, label) {
|
|
844
|
+
const fullLabel = `[@jsii/kernel:timing] ${label}`;
|
|
845
|
+
if (this.debugTimingEnabled) {
|
|
846
|
+
console.time(fullLabel);
|
|
847
|
+
}
|
|
848
|
+
try {
|
|
849
|
+
return cb();
|
|
850
|
+
}
|
|
851
|
+
finally {
|
|
852
|
+
if (this.debugTimingEnabled) {
|
|
853
|
+
console.timeEnd(fullLabel);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
828
857
|
/**
|
|
829
858
|
* Ensures that `fn` is called and defends against beginning to invoke
|
|
830
859
|
* async methods until fn finishes (successfully or not).
|
package/lib/link.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates directories containing hard links if possible, and falls back on
|
|
3
|
+
* copy otherwise.
|
|
4
|
+
*
|
|
5
|
+
* @param existing is the original file or directory to link.
|
|
6
|
+
* @param destination is the nbew file or directory to create.
|
|
7
|
+
*/
|
|
8
|
+
export declare function link(existing: string, destination: string): void;
|
|
9
|
+
//# sourceMappingURL=link.d.ts.map
|
package/lib/link.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.link = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
/**
|
|
7
|
+
* Creates directories containing hard links if possible, and falls back on
|
|
8
|
+
* copy otherwise.
|
|
9
|
+
*
|
|
10
|
+
* @param existing is the original file or directory to link.
|
|
11
|
+
* @param destination is the nbew file or directory to create.
|
|
12
|
+
*/
|
|
13
|
+
function link(existing, destination) {
|
|
14
|
+
const stat = (0, fs_1.statSync)(existing);
|
|
15
|
+
if (!stat.isDirectory()) {
|
|
16
|
+
try {
|
|
17
|
+
(0, fs_1.linkSync)(existing, destination);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
(0, fs_1.copyFileSync)(existing, destination);
|
|
21
|
+
}
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
(0, fs_1.mkdirSync)(destination, { recursive: true });
|
|
25
|
+
for (const file of (0, fs_1.readdirSync)(existing)) {
|
|
26
|
+
link((0, path_1.join)(existing, file), (0, path_1.join)(destination, file));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.link = link;
|
|
30
|
+
//# sourceMappingURL=link.js.map
|
package/lib/objects.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare function objectReference(obj: unknown): api.ObjRef | undefined;
|
|
|
17
17
|
/**
|
|
18
18
|
* Set the JSII FQN for classes produced by a given constructor
|
|
19
19
|
*/
|
|
20
|
-
export declare function tagJsiiConstructor(constructor: any, fqn: string): void;
|
|
20
|
+
export declare function tagJsiiConstructor(constructor: any, fqn: string, version: string): void;
|
|
21
21
|
/**
|
|
22
22
|
* Table of JSII objects
|
|
23
23
|
*
|
package/lib/objects.js
CHANGED
|
@@ -15,7 +15,7 @@ const IFACES_SYMBOL = Symbol.for('$__jsii__interfaces__$');
|
|
|
15
15
|
/**
|
|
16
16
|
* Symbol we use to tag the constructor of a JSII class
|
|
17
17
|
*/
|
|
18
|
-
const
|
|
18
|
+
const JSII_RTTI_SYMBOL = Symbol.for('jsii.rtti');
|
|
19
19
|
/**
|
|
20
20
|
* Get the JSII fqn for an object (if available)
|
|
21
21
|
*
|
|
@@ -25,7 +25,7 @@ const JSII_SYMBOL = Symbol.for('__jsii__');
|
|
|
25
25
|
*/
|
|
26
26
|
function jsiiTypeFqn(obj) {
|
|
27
27
|
var _a;
|
|
28
|
-
return (_a = obj.constructor[
|
|
28
|
+
return (_a = obj.constructor[JSII_RTTI_SYMBOL]) === null || _a === void 0 ? void 0 : _a.fqn;
|
|
29
29
|
}
|
|
30
30
|
exports.jsiiTypeFqn = jsiiTypeFqn;
|
|
31
31
|
/**
|
|
@@ -72,12 +72,15 @@ function tagObject(obj, objid, interfaces) {
|
|
|
72
72
|
/**
|
|
73
73
|
* Set the JSII FQN for classes produced by a given constructor
|
|
74
74
|
*/
|
|
75
|
-
function tagJsiiConstructor(constructor, fqn) {
|
|
76
|
-
Object.
|
|
75
|
+
function tagJsiiConstructor(constructor, fqn, version) {
|
|
76
|
+
if (Object.prototype.hasOwnProperty.call(constructor, JSII_RTTI_SYMBOL)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
Object.defineProperty(constructor, JSII_RTTI_SYMBOL, {
|
|
77
80
|
configurable: false,
|
|
78
81
|
enumerable: false,
|
|
79
82
|
writable: false,
|
|
80
|
-
value: { fqn },
|
|
83
|
+
value: { fqn, version },
|
|
81
84
|
});
|
|
82
85
|
}
|
|
83
86
|
exports.tagJsiiConstructor = tagJsiiConstructor;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultCacheRoot = void 0;
|
|
4
|
+
const os_1 = require("os");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
function defaultCacheRoot() {
|
|
7
|
+
switch (process.platform) {
|
|
8
|
+
case 'darwin':
|
|
9
|
+
if (process.env.HOME)
|
|
10
|
+
return (0, path_1.join)(process.env.HOME, 'Library', 'Caches', 'com.amazonaws.jsii', 'package-cache');
|
|
11
|
+
break;
|
|
12
|
+
case 'linux':
|
|
13
|
+
if (process.env.HOME)
|
|
14
|
+
return (0, path_1.join)(process.env.HOME, '.cache', 'aws', 'jsii', 'package-cache');
|
|
15
|
+
break;
|
|
16
|
+
case 'win32':
|
|
17
|
+
if (process.env.LOCALAPPDATA)
|
|
18
|
+
return (0, path_1.join)(process.env.LOCALAPPDATA, 'AWS', 'jsii', 'package-cache');
|
|
19
|
+
break;
|
|
20
|
+
default:
|
|
21
|
+
// Fall back on putting in tmpdir()
|
|
22
|
+
}
|
|
23
|
+
return (0, path_1.join)((0, os_1.tmpdir)(), 'aws-jsii-package-cache');
|
|
24
|
+
}
|
|
25
|
+
exports.defaultCacheRoot = defaultCacheRoot;
|
|
26
|
+
//# sourceMappingURL=default-cache-root.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as tar from 'tar';
|
|
2
|
+
export declare type ExtractOptions = Omit<tar.ExtractOptions & tar.FileOptions, 'file' | 'cwd'>;
|
|
3
|
+
export interface ExtractResult {
|
|
4
|
+
/**
|
|
5
|
+
* The path in which the extracted files are located
|
|
6
|
+
*/
|
|
7
|
+
readonly path: string;
|
|
8
|
+
/**
|
|
9
|
+
* When `'hit'`, the data was already present in cache and was returned from
|
|
10
|
+
* cache.
|
|
11
|
+
*
|
|
12
|
+
* When `'miss'`, the data was extracted into the caache and returned from
|
|
13
|
+
* cache.
|
|
14
|
+
*
|
|
15
|
+
* When `undefined`, the cache is not enabled.
|
|
16
|
+
*/
|
|
17
|
+
readonly cache?: 'hit' | 'miss';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Extracts the content of a tarball, possibly caching it on disk.
|
|
21
|
+
*
|
|
22
|
+
* @param file is the path to the tarball to be extracted.
|
|
23
|
+
* @param options are options to pass to `tar.extract`
|
|
24
|
+
* @param comments are included in the cache key, when caching is enabled.
|
|
25
|
+
*
|
|
26
|
+
* @returns the result of the extraction.
|
|
27
|
+
*/
|
|
28
|
+
export declare function extract(file: string, options: ExtractOptions, ...comments: readonly string[]): ExtractResult;
|
|
29
|
+
/** @internal */
|
|
30
|
+
export declare function getPackageCacheEnabled(): boolean;
|
|
31
|
+
/** @internal */
|
|
32
|
+
export declare function setPackageCacheEnabled(value: boolean): void;
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.setPackageCacheEnabled = exports.getPackageCacheEnabled = exports.extract = void 0;
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const os_1 = require("os");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const tar = require("tar");
|
|
9
|
+
const disk_cache_1 = require("../disk-cache");
|
|
10
|
+
const default_cache_root_1 = require("./default-cache-root");
|
|
11
|
+
let packageCacheEnabled = ((_a = process.env.JSII_RUNTIME_PACKAGE_CACHE) === null || _a === void 0 ? void 0 : _a.toLocaleUpperCase()) === 'enabled';
|
|
12
|
+
/**
|
|
13
|
+
* Extracts the content of a tarball, possibly caching it on disk.
|
|
14
|
+
*
|
|
15
|
+
* @param file is the path to the tarball to be extracted.
|
|
16
|
+
* @param options are options to pass to `tar.extract`
|
|
17
|
+
* @param comments are included in the cache key, when caching is enabled.
|
|
18
|
+
*
|
|
19
|
+
* @returns the result of the extraction.
|
|
20
|
+
*/
|
|
21
|
+
function extract(file, options, ...comments) {
|
|
22
|
+
return (packageCacheEnabled ? extractToCache : extractToTemporary)(file, options, ...comments);
|
|
23
|
+
}
|
|
24
|
+
exports.extract = extract;
|
|
25
|
+
function extractToCache(file, options = {}, ...comments) {
|
|
26
|
+
var _a;
|
|
27
|
+
const cacheRoot = (_a = process.env.JSII_RUNTIME_PACKAGE_CACHE_ROOT) !== null && _a !== void 0 ? _a : (0, default_cache_root_1.defaultCacheRoot)();
|
|
28
|
+
const cache = disk_cache_1.DiskCache.inDirectory(cacheRoot);
|
|
29
|
+
const entry = cache.entryFor(file, ...comments);
|
|
30
|
+
return entry.lock((lock) => {
|
|
31
|
+
let cache = 'hit';
|
|
32
|
+
if (!entry.pathExists) {
|
|
33
|
+
const tmpPath = `${entry.path}.tmp`;
|
|
34
|
+
(0, fs_1.mkdirSync)(tmpPath, { recursive: true });
|
|
35
|
+
try {
|
|
36
|
+
untarInto({
|
|
37
|
+
...options,
|
|
38
|
+
cwd: tmpPath,
|
|
39
|
+
file,
|
|
40
|
+
});
|
|
41
|
+
(0, fs_1.renameSync)(tmpPath, entry.path);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
(0, fs_1.rmSync)(entry.path, { force: true, recursive: true });
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
cache = 'miss';
|
|
48
|
+
}
|
|
49
|
+
lock.touch();
|
|
50
|
+
return { path: entry.path, cache };
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function extractToTemporary(file, options = {}) {
|
|
54
|
+
const path = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'jsii-runtime-untar-'));
|
|
55
|
+
untarInto({ ...options, cwd: path, file });
|
|
56
|
+
return { path };
|
|
57
|
+
}
|
|
58
|
+
function untarInto(options) {
|
|
59
|
+
try {
|
|
60
|
+
tar.extract({ ...options, sync: true });
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
(0, fs_1.rmSync)(options.cwd, { force: true, recursive: true });
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** @internal */
|
|
68
|
+
function getPackageCacheEnabled() {
|
|
69
|
+
return packageCacheEnabled;
|
|
70
|
+
}
|
|
71
|
+
exports.getPackageCacheEnabled = getPackageCacheEnabled;
|
|
72
|
+
/** @internal */
|
|
73
|
+
function setPackageCacheEnabled(value) {
|
|
74
|
+
packageCacheEnabled = value;
|
|
75
|
+
}
|
|
76
|
+
exports.setPackageCacheEnabled = setPackageCacheEnabled;
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsii/kernel",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.67.0",
|
|
4
4
|
"description": "kernel for jsii execution environment",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": {
|
|
@@ -31,17 +31,19 @@
|
|
|
31
31
|
"package": "package-js"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@jsii/spec": "^1.
|
|
34
|
+
"@jsii/spec": "^1.67.0",
|
|
35
35
|
"fs-extra": "^10.1.0",
|
|
36
|
+
"lockfile": "^1.0.4",
|
|
36
37
|
"tar": "^6.1.11"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"@scope/jsii-calc-base": "^1.
|
|
40
|
-
"@scope/jsii-calc-lib": "^1.
|
|
40
|
+
"@scope/jsii-calc-base": "^1.67.0",
|
|
41
|
+
"@scope/jsii-calc-lib": "^1.67.0",
|
|
41
42
|
"@types/fs-extra": "^9.0.13",
|
|
43
|
+
"@types/lockfile": "^1.0.2",
|
|
42
44
|
"@types/tar": "^6.1.2",
|
|
43
45
|
"jest-expect-message": "^1.0.2",
|
|
44
|
-
"jsii-build-tools": "^1.
|
|
46
|
+
"jsii-build-tools": "^1.67.0",
|
|
45
47
|
"jsii-calc": "^3.20.120"
|
|
46
48
|
}
|
|
47
49
|
}
|