@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.
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ export declare function digestFile(path: string, ...comments: readonly string[]): Buffer;
3
+ //# sourceMappingURL=digest-file.d.ts.map
@@ -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,2 @@
1
+ export * from './disk-cache';
2
+ //# sourceMappingURL=index.d.ts.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
- var _a, _b;
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((_b = assmSpec.types) !== null && _b !== void 0 ? _b : {}).length,
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 JSII_SYMBOL = Symbol.for('__jsii__');
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[JSII_SYMBOL]) === null || _a === void 0 ? void 0 : _a.fqn;
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.defineProperty(constructor, JSII_SYMBOL, {
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,2 @@
1
+ export declare function defaultCacheRoot(): string;
2
+ //# sourceMappingURL=default-cache-root.d.ts.map
@@ -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.65.0",
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.65.0",
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.65.0",
40
- "@scope/jsii-calc-lib": "^1.65.0",
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.65.0",
46
+ "jsii-build-tools": "^1.67.0",
45
47
  "jsii-calc": "^3.20.120"
46
48
  }
47
49
  }