querysub 0.433.0 → 0.436.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.
Files changed (74) hide show
  1. package/.eslintrc.js +50 -50
  2. package/bin/deploy.js +0 -0
  3. package/bin/function.js +0 -0
  4. package/bin/server.js +0 -0
  5. package/costsBenefits.txt +115 -115
  6. package/deploy.ts +2 -2
  7. package/package.json +1 -1
  8. package/spec.txt +1192 -1192
  9. package/src/-a-archives/archives.ts +202 -202
  10. package/src/-a-archives/archivesBackBlaze.ts +1 -0
  11. package/src/-a-archives/archivesDisk.ts +454 -454
  12. package/src/-a-auth/certs.ts +540 -540
  13. package/src/-a-auth/node-forge-ed25519.d.ts +16 -16
  14. package/src/-b-authorities/dnsAuthority.ts +138 -138
  15. package/src/-c-identity/IdentityController.ts +258 -258
  16. package/src/-d-trust/NetworkTrust2.ts +180 -180
  17. package/src/-e-certs/EdgeCertController.ts +252 -252
  18. package/src/-e-certs/certAuthority.ts +201 -201
  19. package/src/-f-node-discovery/NodeDiscovery.ts +640 -640
  20. package/src/-g-core-values/NodeCapabilities.ts +200 -200
  21. package/src/-h-path-value-serialize/stringSerializer.ts +175 -175
  22. package/src/0-path-value-core/PathValueCommitter.ts +468 -468
  23. package/src/0-path-value-core/pathValueCore.ts +2 -2
  24. package/src/2-proxy/PathValueProxyWatcher.ts +2542 -2542
  25. package/src/2-proxy/TransactionDelayer.ts +94 -94
  26. package/src/2-proxy/pathDatabaseProxyBase.ts +36 -36
  27. package/src/2-proxy/pathValueProxy.ts +159 -159
  28. package/src/3-path-functions/PathFunctionRunnerMain.ts +87 -87
  29. package/src/3-path-functions/pathFunctionLoader.ts +516 -516
  30. package/src/3-path-functions/tests/rejectTest.ts +76 -76
  31. package/src/4-deploy/deployCheck.ts +6 -6
  32. package/src/4-dom/css.tsx +29 -29
  33. package/src/4-dom/cssTypes.d.ts +211 -211
  34. package/src/4-dom/qreact.tsx +2799 -2799
  35. package/src/4-dom/qreactTest.tsx +410 -410
  36. package/src/4-querysub/permissions.ts +335 -335
  37. package/src/4-querysub/querysubPrediction.ts +483 -483
  38. package/src/5-diagnostics/qreactDebug.tsx +346 -346
  39. package/src/TestController.ts +34 -34
  40. package/src/bits.ts +104 -104
  41. package/src/buffers.ts +69 -69
  42. package/src/diagnostics/ActionsHistory.ts +57 -57
  43. package/src/diagnostics/listenOnDebugger.ts +71 -71
  44. package/src/diagnostics/periodic.ts +111 -111
  45. package/src/diagnostics/trackResources.ts +91 -91
  46. package/src/diagnostics/watchdog.ts +120 -120
  47. package/src/errors.ts +133 -133
  48. package/src/forceProduction.ts +2 -2
  49. package/src/fs.ts +80 -80
  50. package/src/functional/diff.ts +857 -857
  51. package/src/functional/promiseCache.ts +78 -78
  52. package/src/functional/random.ts +8 -8
  53. package/src/functional/stats.ts +60 -60
  54. package/src/heapDumps.ts +665 -665
  55. package/src/https.ts +1 -1
  56. package/src/library-components/AspectSizedComponent.tsx +87 -87
  57. package/src/library-components/ButtonSelector.tsx +64 -64
  58. package/src/library-components/DropdownCustom.tsx +150 -150
  59. package/src/library-components/DropdownSelector.tsx +31 -31
  60. package/src/library-components/InlinePopup.tsx +66 -66
  61. package/src/misc/color.ts +29 -29
  62. package/src/misc/hash.ts +83 -83
  63. package/src/misc/ipPong.js +13 -13
  64. package/src/misc/networking.ts +1 -1
  65. package/src/misc/random.ts +44 -44
  66. package/src/misc.ts +196 -196
  67. package/src/path.ts +255 -255
  68. package/src/persistentLocalStore.ts +41 -41
  69. package/src/promise.ts +14 -14
  70. package/src/storage/fileSystemPointer.ts +71 -71
  71. package/src/test/heapProcess.ts +35 -35
  72. package/src/zip.ts +15 -15
  73. package/tsconfig.json +26 -26
  74. package/yarnSpec.txt +56 -56
@@ -1,72 +1,72 @@
1
- import { lazy } from "socket-function/src/caching";
2
- import { nextId } from "socket-function/src/misc";
3
-
4
- const objectStoreName = "fileSystemPointerDB";
5
- const db = lazy(async () => {
6
- let db = indexedDB.open("fileSystemPointerDB_f298e962-bd8a-46b9-8098-25db633f4ed3", 1);
7
- db.addEventListener("upgradeneeded", () => {
8
- db.result.createObjectStore(objectStoreName, {});
9
- });
10
- await new Promise(resolve => db.addEventListener("success", resolve));
11
- return db.result;
12
- });
13
- async function getTransaction() {
14
- let database = await db();
15
- if (!database) return undefined;
16
- return database.transaction(objectStoreName, "readwrite").objectStore(objectStoreName);
17
- }
18
- async function write(key: string, value: FileSystemFileHandle | FileSystemDirectoryHandle) {
19
- let transaction = await getTransaction();
20
- if (!transaction) return;
21
- let req = transaction.put(value, key);
22
- await new Promise((resolve, reject) => {
23
- req.addEventListener("success", resolve);
24
- req.addEventListener("error", reject);
25
- });
26
- }
27
- async function read(key: string): Promise<FileSystemFileHandle | FileSystemDirectoryHandle | undefined> {
28
- let transaction = await getTransaction();
29
- if (!transaction) return;
30
- let req = transaction.get(key);
31
- await new Promise((resolve, reject) => {
32
- req.addEventListener("success", resolve);
33
- req.addEventListener("error", reject);
34
- });
35
- return req.result;
36
- }
37
-
38
- export type FileSystemPointer = string;
39
- export async function storeFileSystemPointer(config: {
40
- mode: "read" | "readwrite";
41
- handle: FileSystemFileHandle | FileSystemDirectoryHandle;
42
- }): Promise<FileSystemPointer> {
43
- await (config.handle as any).requestPermission({ mode: config.mode });
44
- let key = nextId() + "_" + config.mode;
45
- await write(key, config.handle);
46
- return key;
47
- }
48
-
49
- export async function getFileSystemPointer(config: {
50
- pointer: FileSystemPointer;
51
- }): Promise<{
52
- // NOTE: We have to call requestPermission, so... user activation is required (as in,
53
- // this need to be called inside of a button).
54
- // IMPORTANT! In some circumstances user activation is not required (with multiple tabs,
55
- // and potentially with https://developer.chrome.com/blog/persistent-permissions-for-the-file-system-access-api),
56
- // so... trying to call onUserActivation immmediately is a good idea (although it might throw).
57
- onUserActivation(modeOverride?: "read" | "readwrite"): Promise<FileSystemFileHandle | FileSystemDirectoryHandle>
58
- } | undefined
59
- > {
60
- const handle = await read(config.pointer);
61
- if (!handle) return;
62
- let mode = config.pointer.split("_").at(-1);
63
- return {
64
- async onUserActivation(modeOverride) {
65
- let testMode = await (handle as any).queryPermission({ mode: mode });
66
- if (testMode !== mode) {
67
- await (handle as any).requestPermission({ mode: modeOverride ?? mode });
68
- }
69
- return handle;
70
- }
71
- };
1
+ import { lazy } from "socket-function/src/caching";
2
+ import { nextId } from "socket-function/src/misc";
3
+
4
+ const objectStoreName = "fileSystemPointerDB";
5
+ const db = lazy(async () => {
6
+ let db = indexedDB.open("fileSystemPointerDB_f298e962-bd8a-46b9-8098-25db633f4ed3", 1);
7
+ db.addEventListener("upgradeneeded", () => {
8
+ db.result.createObjectStore(objectStoreName, {});
9
+ });
10
+ await new Promise(resolve => db.addEventListener("success", resolve));
11
+ return db.result;
12
+ });
13
+ async function getTransaction() {
14
+ let database = await db();
15
+ if (!database) return undefined;
16
+ return database.transaction(objectStoreName, "readwrite").objectStore(objectStoreName);
17
+ }
18
+ async function write(key: string, value: FileSystemFileHandle | FileSystemDirectoryHandle) {
19
+ let transaction = await getTransaction();
20
+ if (!transaction) return;
21
+ let req = transaction.put(value, key);
22
+ await new Promise((resolve, reject) => {
23
+ req.addEventListener("success", resolve);
24
+ req.addEventListener("error", reject);
25
+ });
26
+ }
27
+ async function read(key: string): Promise<FileSystemFileHandle | FileSystemDirectoryHandle | undefined> {
28
+ let transaction = await getTransaction();
29
+ if (!transaction) return;
30
+ let req = transaction.get(key);
31
+ await new Promise((resolve, reject) => {
32
+ req.addEventListener("success", resolve);
33
+ req.addEventListener("error", reject);
34
+ });
35
+ return req.result;
36
+ }
37
+
38
+ export type FileSystemPointer = string;
39
+ export async function storeFileSystemPointer(config: {
40
+ mode: "read" | "readwrite";
41
+ handle: FileSystemFileHandle | FileSystemDirectoryHandle;
42
+ }): Promise<FileSystemPointer> {
43
+ await (config.handle as any).requestPermission({ mode: config.mode });
44
+ let key = nextId() + "_" + config.mode;
45
+ await write(key, config.handle);
46
+ return key;
47
+ }
48
+
49
+ export async function getFileSystemPointer(config: {
50
+ pointer: FileSystemPointer;
51
+ }): Promise<{
52
+ // NOTE: We have to call requestPermission, so... user activation is required (as in,
53
+ // this need to be called inside of a button).
54
+ // IMPORTANT! In some circumstances user activation is not required (with multiple tabs,
55
+ // and potentially with https://developer.chrome.com/blog/persistent-permissions-for-the-file-system-access-api),
56
+ // so... trying to call onUserActivation immmediately is a good idea (although it might throw).
57
+ onUserActivation(modeOverride?: "read" | "readwrite"): Promise<FileSystemFileHandle | FileSystemDirectoryHandle>
58
+ } | undefined
59
+ > {
60
+ const handle = await read(config.pointer);
61
+ if (!handle) return;
62
+ let mode = config.pointer.split("_").at(-1);
63
+ return {
64
+ async onUserActivation(modeOverride) {
65
+ let testMode = await (handle as any).queryPermission({ mode: mode });
66
+ if (testMode !== mode) {
67
+ await (handle as any).requestPermission({ mode: modeOverride ?? mode });
68
+ }
69
+ return handle;
70
+ }
71
+ };
72
72
  }
@@ -1,36 +1,36 @@
1
- import { formatNumber } from "socket-function/src/formatting/format";
2
- import { parseHeapSnapshot, processAndSummarizeHeapsnapshot } from "../heapDumps";
3
- import fs from "fs";
4
-
5
- async function heapProcess() {
6
- /*
7
- let targetRatePerSecond = 50;
8
- let startTime = Date.now();
9
-
10
- for(let i = 0; i < 300 * 300; i++) {
11
- sat_functions.setValues([i]);
12
-
13
- while (true) {
14
- let rate = i / (Date.now() - startTime) * 1000;
15
- if(rate < targetRatePerSecond) break;
16
- await delay(16);
17
- }
18
- }
19
- */
20
-
21
- let buffer = fs.readFileSync("./heapdump.heapsnapshot");
22
- let parsed = await parseHeapSnapshot("stressTest", buffer, () => { });
23
-
24
- let snapshot = await processAndSummarizeHeapsnapshot(parsed, () => { }, {
25
-
26
- });
27
- console.log();
28
-
29
- console.log(`Total ${formatNumber(snapshot.total)}`);
30
- let values = Object.values(snapshot.summary);
31
- values.sort((a, b) => b.sum - a.sum);
32
- for (let value of values.slice(0, 100)) {
33
- console.log(`${formatNumber(value.sum)} (${value.count})`.padEnd(20, "") + " " + value.key + ` (ex id ${value.firstId})`);
34
- }
35
- }
1
+ import { formatNumber } from "socket-function/src/formatting/format";
2
+ import { parseHeapSnapshot, processAndSummarizeHeapsnapshot } from "../heapDumps";
3
+ import fs from "fs";
4
+
5
+ async function heapProcess() {
6
+ /*
7
+ let targetRatePerSecond = 50;
8
+ let startTime = Date.now();
9
+
10
+ for(let i = 0; i < 300 * 300; i++) {
11
+ sat_functions.setValues([i]);
12
+
13
+ while (true) {
14
+ let rate = i / (Date.now() - startTime) * 1000;
15
+ if(rate < targetRatePerSecond) break;
16
+ await delay(16);
17
+ }
18
+ }
19
+ */
20
+
21
+ let buffer = fs.readFileSync("./heapdump.heapsnapshot");
22
+ let parsed = await parseHeapSnapshot("stressTest", buffer, () => { });
23
+
24
+ let snapshot = await processAndSummarizeHeapsnapshot(parsed, () => { }, {
25
+
26
+ });
27
+ console.log();
28
+
29
+ console.log(`Total ${formatNumber(snapshot.total)}`);
30
+ let values = Object.values(snapshot.summary);
31
+ values.sort((a, b) => b.sum - a.sum);
32
+ for (let value of values.slice(0, 100)) {
33
+ console.log(`${formatNumber(value.sum)} (${value.count})`.padEnd(20, "") + " " + value.key + ` (ex id ${value.firstId})`);
34
+ }
35
+ }
36
36
  heapProcess().catch(e => console.error(e)).finally(() => process.exit());
package/src/zip.ts CHANGED
@@ -1,15 +1,15 @@
1
- import { isNode } from "socket-function/src/misc";
2
- import { measureBlock, measureFnc } from "socket-function/src/profiling/measure";
3
- import zlib from "zlib";
4
- import * as pako from "pako";
5
-
6
- import { setFlag } from "socket-function/require/compileFlags";
7
- import { unzipThreaded } from "./zipThreaded";
8
- import debugbreak from "debugbreak";
9
- import { formatNumber } from "socket-function/src/formatting/format";
10
- import { runInSerial } from "socket-function/src/batching";
11
- import { MaybePromise } from "socket-function/src/types";
12
- import { Zip } from "socket-function/src/Zip";
13
- setFlag(require, "pako", "allowclient", true);
14
-
15
- export { Zip };
1
+ import { isNode } from "socket-function/src/misc";
2
+ import { measureBlock, measureFnc } from "socket-function/src/profiling/measure";
3
+ import zlib from "zlib";
4
+ import * as pako from "pako";
5
+
6
+ import { setFlag } from "socket-function/require/compileFlags";
7
+ import { unzipThreaded } from "./zipThreaded";
8
+ import debugbreak from "debugbreak";
9
+ import { formatNumber } from "socket-function/src/formatting/format";
10
+ import { runInSerial } from "socket-function/src/batching";
11
+ import { MaybePromise } from "socket-function/src/types";
12
+ import { Zip } from "socket-function/src/Zip";
13
+ setFlag(require, "pako", "allowclient", true);
14
+
15
+ export { Zip };
package/tsconfig.json CHANGED
@@ -1,27 +1,27 @@
1
- {
2
- "compilerOptions": {
3
- "strict": true,
4
- "module": "CommonJS",
5
- "esModuleInterop": true,
6
- "allowSyntheticDefaultImports": true,
7
- "moduleResolution": "node",
8
- "target": "es2018",
9
- "lib": [
10
- "ESNext",
11
- "dom",
12
- "dom.iterable"
13
- ],
14
- "jsx": "react",
15
- "alwaysStrict": true,
16
- "jsxFactory": "qreact.createElement",
17
- "jsxFragmentFactory": "qreact.Fragment",
18
- "types": [
19
- "node",
20
- ],
21
- "experimentalDecorators": true,
22
- "emitDecoratorMetadata": false,
23
- "skipLibCheck": true,
24
- "inlineSourceMap": true,
25
- "inlineSources": true,
26
- }
1
+ {
2
+ "compilerOptions": {
3
+ "strict": true,
4
+ "module": "CommonJS",
5
+ "esModuleInterop": true,
6
+ "allowSyntheticDefaultImports": true,
7
+ "moduleResolution": "node",
8
+ "target": "es2018",
9
+ "lib": [
10
+ "ESNext",
11
+ "dom",
12
+ "dom.iterable"
13
+ ],
14
+ "jsx": "react",
15
+ "alwaysStrict": true,
16
+ "jsxFactory": "qreact.createElement",
17
+ "jsxFragmentFactory": "qreact.Fragment",
18
+ "types": [
19
+ "node",
20
+ ],
21
+ "experimentalDecorators": true,
22
+ "emitDecoratorMetadata": false,
23
+ "skipLibCheck": true,
24
+ "inlineSourceMap": true,
25
+ "inlineSources": true,
26
+ }
27
27
  }
package/yarnSpec.txt CHANGED
@@ -1,56 +1,56 @@
1
- - better yarn, `packagedownload`?
2
-
3
- ACTUALLY, a lot of this, BUT, have the config format just entirely describe the on disk format, being relative to where each package is located. That way it is obvious how you will change how a specific package resolves just inside of another package, or if one package is using a custom version, etc, etc.
4
-
5
- `npm -run packagedownload add package-name`, `npm -run packagedownload install`
6
- add
7
- --dry-run
8
- --force
9
- --update
10
- --dev
11
- --nolink
12
- install
13
- --dry-run
14
- --force
15
- --update
16
- --nolink
17
- - DON'T run scripts by default, only running them if requested via `"execute": {}` in the package.json configuration
18
- - With a "request-execute" field, which warns if you use a package and don't let it execute (it will still run it though)
19
- - On install performs a "light" check, only checking the "package.json".version of packages (or package, if a package is specified), not updating anything that looks up to date
20
- - Has a --force flag, which will always delete all packages and install a new one (or rather, install all packages, as we will always delete and install the new one when we are installing)
21
- - Still supports a --production mode, which doesn't install dev dependencies
22
- - HAS to support "cpu", and "os" restrictions
23
- - But, still support "ignore-engines", to skip these
24
- - ALWAYS flat, warning on conflicts, using package "resolutions" to decide which one to use
25
- - Although, maybe we can have "sandbox", which allows certain dependencies to be told to install all of their dependencies as nested? We won't be able to do partial sandboxing, unless the package is a few levels deep, and we pick the package directly above it (which doesn't give us full control, but is probably enough).
26
- - Call the lock file `resolvedversions.json`, as it isn't for locking, it is for specifying which versions of packages should be used (if compatible with the rough version in package.json)
27
- - Avoid nesting automatically, by having any install check if the current folder is in a node_modules folder, and if so uses the lock file above that, and installs the dependencies as siblings in that node_modules folder
28
- - Allow packages to use `{ "force-sandbox": true }`, to force their dependencies to be installed in a nested node_modules (sandboxing which also cause the child yarn.lock to be checked before the parent yarn.lock)
29
- - Greatly simplified lock file, given that we generally won't have nested dependencies
30
- - The lock file can give more metadata, such as the full chain of dependencies to the root package.json dependency, as well as package sizes and file counts
31
- - Marks which dependencies are dev only (or only included because of a dev only dependency)
32
- - Support for "link" inside of the package json, which instead works like: `{ "local": { "shard": "../shard/" } }`, which uses those paths when they exist
33
- - A "nolink" option will disable this
34
- - Creates symlinks
35
- - Makes symlinks for all nested dependencies as well
36
- - Adds metadata in the lock file to indicate the modules are being symlinked?
37
- - Ability to install only a specific package, aka, `install shard`, which uses the version in the lock file (or package.json)
38
- - typenode can start installing on require, only installing the required package
39
- - There would have to be a way to turn it off, ex, with `typenodecompat`, which wouldn't install packages. That way you could use typenode without messing up your node_modules folders
40
- - This mode could also store the dist folders somewhere else, or even... just not store them, eliminating caching?
41
- - We could even use packagedownload via an import, so we don't need to spawn a new processes!
42
- - This would allow packagedownload to maintain various caches, making it a lot more efficient when called multiple times.
43
- - Add a TODO to support some form of tree-shaking. As in, if we detect out of the module only "x" and "y" are included, then we can strip the file of everything unrelated to "x" and "y" (which is not easy, but... not REALLY hard either). The idea, is not to reduce file size (who cares about that?), but actually to create unused requires, which we can then strip as well!
44
- - We would need a flag to know if required modules have side-effects or not (package.json has a flag for this, and we can also support a `module.sideeffects = true` flag)
45
- - And, we might as well have a package.json flag to set side-effects on nested packages, probably recursively.
46
- - If the package is marked with "execute" it will be recursively installed as well, unless it has "no-recursive" in the package.json
47
- - Can be added to a package directly, which ADDS A BOOTSTRAPPER, by default, as a .js file, and adds a reference to a new scripts step ("packagedownload.js"?), or some similar step, in package.json. It can then be also called in your runs steps, ex, `node ./packagedownload.js && npm -run typenode ./index.ts`, which then allows `npm -run start` to work after an install (heck, you could even do `git clone git@github.com/user/repo.git ~/repo && cd ~/repo && git -run start`, to easily install it on any system that just has node and git)
48
- - Eventually we could add the ability to install node, using the node version from the package.json (using the upper limit, ex `>=11 <15`, would use node 15), which would mean basically any system could use it.
49
- - Maybe use a global package download cache (which is maintained and kept below a certain percent of available space!)
50
- - `--update-check` and `--update`, to deal with updating yarn.lock (-check just checks and logs potential updates)
51
- - ALSO, "sources", which can be used to map packages to servers other than npm! Ex, github, etc. BUT, unlike the other way of doing it, versions are still supported!
52
- - `{ "sources": { "source-map-support": "https://github.com/user/source-map-support" } }`
53
- - Also supports npm, so you can switch out a package (for your dependencies too), easily
54
- - ALSO, could add support for "dependencies2", to prevent npm and yarn from installing the dependencies (as they don't support "sources"), allowing the package to install them at runtime, allowing for better compatibility
55
- - In conjunction with optionalDependencies make it possible to add dependencies that don't exist in npm
56
- - The lock file will have to mark who set the source, potentially giving multiple setters, with the highest being the one that actual sets the source.
1
+ - better yarn, `packagedownload`?
2
+
3
+ ACTUALLY, a lot of this, BUT, have the config format just entirely describe the on disk format, being relative to where each package is located. That way it is obvious how you will change how a specific package resolves just inside of another package, or if one package is using a custom version, etc, etc.
4
+
5
+ `npm -run packagedownload add package-name`, `npm -run packagedownload install`
6
+ add
7
+ --dry-run
8
+ --force
9
+ --update
10
+ --dev
11
+ --nolink
12
+ install
13
+ --dry-run
14
+ --force
15
+ --update
16
+ --nolink
17
+ - DON'T run scripts by default, only running them if requested via `"execute": {}` in the package.json configuration
18
+ - With a "request-execute" field, which warns if you use a package and don't let it execute (it will still run it though)
19
+ - On install performs a "light" check, only checking the "package.json".version of packages (or package, if a package is specified), not updating anything that looks up to date
20
+ - Has a --force flag, which will always delete all packages and install a new one (or rather, install all packages, as we will always delete and install the new one when we are installing)
21
+ - Still supports a --production mode, which doesn't install dev dependencies
22
+ - HAS to support "cpu", and "os" restrictions
23
+ - But, still support "ignore-engines", to skip these
24
+ - ALWAYS flat, warning on conflicts, using package "resolutions" to decide which one to use
25
+ - Although, maybe we can have "sandbox", which allows certain dependencies to be told to install all of their dependencies as nested? We won't be able to do partial sandboxing, unless the package is a few levels deep, and we pick the package directly above it (which doesn't give us full control, but is probably enough).
26
+ - Call the lock file `resolvedversions.json`, as it isn't for locking, it is for specifying which versions of packages should be used (if compatible with the rough version in package.json)
27
+ - Avoid nesting automatically, by having any install check if the current folder is in a node_modules folder, and if so uses the lock file above that, and installs the dependencies as siblings in that node_modules folder
28
+ - Allow packages to use `{ "force-sandbox": true }`, to force their dependencies to be installed in a nested node_modules (sandboxing which also cause the child yarn.lock to be checked before the parent yarn.lock)
29
+ - Greatly simplified lock file, given that we generally won't have nested dependencies
30
+ - The lock file can give more metadata, such as the full chain of dependencies to the root package.json dependency, as well as package sizes and file counts
31
+ - Marks which dependencies are dev only (or only included because of a dev only dependency)
32
+ - Support for "link" inside of the package json, which instead works like: `{ "local": { "shard": "../shard/" } }`, which uses those paths when they exist
33
+ - A "nolink" option will disable this
34
+ - Creates symlinks
35
+ - Makes symlinks for all nested dependencies as well
36
+ - Adds metadata in the lock file to indicate the modules are being symlinked?
37
+ - Ability to install only a specific package, aka, `install shard`, which uses the version in the lock file (or package.json)
38
+ - typenode can start installing on require, only installing the required package
39
+ - There would have to be a way to turn it off, ex, with `typenodecompat`, which wouldn't install packages. That way you could use typenode without messing up your node_modules folders
40
+ - This mode could also store the dist folders somewhere else, or even... just not store them, eliminating caching?
41
+ - We could even use packagedownload via an import, so we don't need to spawn a new processes!
42
+ - This would allow packagedownload to maintain various caches, making it a lot more efficient when called multiple times.
43
+ - Add a TODO to support some form of tree-shaking. As in, if we detect out of the module only "x" and "y" are included, then we can strip the file of everything unrelated to "x" and "y" (which is not easy, but... not REALLY hard either). The idea, is not to reduce file size (who cares about that?), but actually to create unused requires, which we can then strip as well!
44
+ - We would need a flag to know if required modules have side-effects or not (package.json has a flag for this, and we can also support a `module.sideeffects = true` flag)
45
+ - And, we might as well have a package.json flag to set side-effects on nested packages, probably recursively.
46
+ - If the package is marked with "execute" it will be recursively installed as well, unless it has "no-recursive" in the package.json
47
+ - Can be added to a package directly, which ADDS A BOOTSTRAPPER, by default, as a .js file, and adds a reference to a new scripts step ("packagedownload.js"?), or some similar step, in package.json. It can then be also called in your runs steps, ex, `node ./packagedownload.js && npm -run typenode ./index.ts`, which then allows `npm -run start` to work after an install (heck, you could even do `git clone git@github.com/user/repo.git ~/repo && cd ~/repo && git -run start`, to easily install it on any system that just has node and git)
48
+ - Eventually we could add the ability to install node, using the node version from the package.json (using the upper limit, ex `>=11 <15`, would use node 15), which would mean basically any system could use it.
49
+ - Maybe use a global package download cache (which is maintained and kept below a certain percent of available space!)
50
+ - `--update-check` and `--update`, to deal with updating yarn.lock (-check just checks and logs potential updates)
51
+ - ALSO, "sources", which can be used to map packages to servers other than npm! Ex, github, etc. BUT, unlike the other way of doing it, versions are still supported!
52
+ - `{ "sources": { "source-map-support": "https://github.com/user/source-map-support" } }`
53
+ - Also supports npm, so you can switch out a package (for your dependencies too), easily
54
+ - ALSO, could add support for "dependencies2", to prevent npm and yarn from installing the dependencies (as they don't support "sources"), allowing the package to install them at runtime, allowing for better compatibility
55
+ - In conjunction with optionalDependencies make it possible to add dependencies that don't exist in npm
56
+ - The lock file will have to mark who set the source, potentially giving multiple setters, with the highest being the one that actual sets the source.