jopi-node-space 0.0.4 → 0.0.6
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/bun.lock +10 -0
- package/dist/__global.d.ts +25 -2
- package/dist/__global.js +1 -1
- package/dist/__global.js.map +1 -1
- package/dist/_fs_s.js +55 -1
- package/dist/_fs_s.js.map +1 -1
- package/dist/_term.js +14 -1
- package/dist/_term.js.map +1 -1
- package/dist/_timer.d.ts +1 -1
- package/dist/_timer.js.map +1 -1
- package/package.json +8 -6
- package/src/__global.ts +30 -3
- package/src/_fs_s.ts +67 -1
- package/src/_term.ts +14 -1
- package/src/_timer.ts +2 -2
package/bun.lock
CHANGED
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
"workspaces": {
|
|
4
4
|
"": {
|
|
5
5
|
"name": "jopi-node-space",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"mime-types": "^3.0.1",
|
|
8
|
+
},
|
|
6
9
|
"devDependencies": {
|
|
7
10
|
"@types/bun": "latest",
|
|
11
|
+
"@types/mime-types": "latest",
|
|
8
12
|
"@types/node": "latest",
|
|
9
13
|
},
|
|
10
14
|
},
|
|
@@ -12,6 +16,8 @@
|
|
|
12
16
|
"packages": {
|
|
13
17
|
"@types/bun": ["@types/bun@1.2.19", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="],
|
|
14
18
|
|
|
19
|
+
"@types/mime-types": ["@types/mime-types@3.0.1", "", {}, "sha512-xRMsfuQbnRq1Ef+C+RKaENOxXX87Ygl38W1vDfPHRku02TgQr+Qd8iivLtAMcR0KF5/29xlnFihkTlbqFrGOVQ=="],
|
|
20
|
+
|
|
15
21
|
"@types/node": ["@types/node@24.1.0", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w=="],
|
|
16
22
|
|
|
17
23
|
"@types/react": ["@types/react@19.1.9", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA=="],
|
|
@@ -20,6 +26,10 @@
|
|
|
20
26
|
|
|
21
27
|
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
|
22
28
|
|
|
29
|
+
"mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
|
|
30
|
+
|
|
31
|
+
"mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
|
|
32
|
+
|
|
23
33
|
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
|
|
24
34
|
}
|
|
25
35
|
}
|
package/dist/__global.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type TimerCallback } from "./_timer";
|
|
2
1
|
declare global {
|
|
3
2
|
var NodeSpace: NodeSpaceType;
|
|
4
3
|
var jopiHotReload: HotReloadType;
|
|
@@ -15,7 +14,7 @@ export interface NodeSpaceType {
|
|
|
15
14
|
app: AppImpl;
|
|
16
15
|
extensionPoints: ExtensionPointImpl;
|
|
17
16
|
term: TerminalImpl;
|
|
18
|
-
fs
|
|
17
|
+
fs: FileSystemImpl;
|
|
19
18
|
applyDefaults<T>(source: T | undefined, defaults: T): T;
|
|
20
19
|
}
|
|
21
20
|
export interface HotReloadType {
|
|
@@ -46,6 +45,7 @@ interface ProcessImpl {
|
|
|
46
45
|
};
|
|
47
46
|
isProduction: boolean;
|
|
48
47
|
}
|
|
48
|
+
export type TimerCallback = () => void | boolean | Promise<void | boolean>;
|
|
49
49
|
interface TimerImpl {
|
|
50
50
|
ONE_SECOND: number;
|
|
51
51
|
ONE_MINUTE: number;
|
|
@@ -55,8 +55,26 @@ interface TimerImpl {
|
|
|
55
55
|
newInterval: (durationInMs: number, callback: TimerCallback) => void;
|
|
56
56
|
deferred: (callback: () => void) => void;
|
|
57
57
|
}
|
|
58
|
+
export interface FileState {
|
|
59
|
+
size: number;
|
|
60
|
+
mtimeMs: number;
|
|
61
|
+
ctimeMs: number;
|
|
62
|
+
birthtimeMs: number;
|
|
63
|
+
isDirectory: () => boolean;
|
|
64
|
+
isFile: () => boolean;
|
|
65
|
+
isSymbolicLink: () => boolean;
|
|
66
|
+
}
|
|
58
67
|
interface FileSystemImpl {
|
|
59
68
|
mkDir: (dirPath: string) => Promise<string | undefined>;
|
|
69
|
+
fileURLToPath: (url: string) => string;
|
|
70
|
+
pathToFileURL: (fsPath: string) => URL;
|
|
71
|
+
getMimeTypeFromName: (fileName: string) => string;
|
|
72
|
+
getFileSize: (filePath: string) => Promise<number>;
|
|
73
|
+
getFileStat: (filePath: string) => Promise<FileState>;
|
|
74
|
+
writeResponseToFile: (response: Response, filePath: string) => Promise<void>;
|
|
75
|
+
createResponseFromFile: (filePath: string, status?: number, headers?: {
|
|
76
|
+
[key: string]: string;
|
|
77
|
+
} | Headers) => Response;
|
|
60
78
|
}
|
|
61
79
|
interface AppImpl {
|
|
62
80
|
onServerSideReady(listener: Listener): void;
|
|
@@ -91,6 +109,7 @@ interface TerminalImpl {
|
|
|
91
109
|
T_RESET: string;
|
|
92
110
|
T_BOLD: string;
|
|
93
111
|
T_UNDERLINE: string;
|
|
112
|
+
T_REWRITE_LINE: string;
|
|
94
113
|
T_CLEAR_LINE: string;
|
|
95
114
|
T_CLEAR_LINE_END: string;
|
|
96
115
|
T_CLEAR_SCREEN: string;
|
|
@@ -109,6 +128,10 @@ interface TerminalImpl {
|
|
|
109
128
|
B_MAGENTA: string;
|
|
110
129
|
B_CYAN: string;
|
|
111
130
|
B_WHITE: string;
|
|
131
|
+
/**
|
|
132
|
+
* Do a console.log, but replace the current line or add a new one.
|
|
133
|
+
*/
|
|
134
|
+
consoleLogErasable: (erase: boolean, ...args: unknown[]) => void;
|
|
112
135
|
colorize(...params: string[]): string;
|
|
113
136
|
cssText(text: string, css: string): void;
|
|
114
137
|
moveUp(n: number): string;
|
package/dist/__global.js
CHANGED
package/dist/__global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"__global.js","sourceRoot":"","sources":["../src/__global.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"__global.js","sourceRoot":"","sources":["../src/__global.ts"],"names":[],"mappings":"AAKA,UAAU,CAAC,SAAS,GAAG,EAAmB,CAAC"}
|
package/dist/_fs_s.js
CHANGED
|
@@ -1,7 +1,61 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import { isBunJs } from "./common.js";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { lookup } from "mime-types";
|
|
6
|
+
import { createReadStream } from "node:fs";
|
|
7
|
+
//region NodeJS adapter
|
|
8
|
+
async function writeResponseToFile(response, filePath) {
|
|
9
|
+
const bufferDonnees = await response.arrayBuffer();
|
|
10
|
+
const bufferNode = Buffer.from(bufferDonnees);
|
|
11
|
+
await fs.writeFile(filePath, bufferNode);
|
|
12
|
+
}
|
|
13
|
+
function nodeStreamToWebStream(nodeStream) {
|
|
14
|
+
return new ReadableStream({
|
|
15
|
+
start(controller) {
|
|
16
|
+
nodeStream.on('data', (chunk) => { controller.enqueue(chunk); });
|
|
17
|
+
nodeStream.on('end', () => { controller.close(); });
|
|
18
|
+
nodeStream.on('error', (err) => { controller.error(err); });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function createResponseFromFile(filePath, status = 200, headers) {
|
|
23
|
+
const nodeReadStream = createReadStream(filePath);
|
|
24
|
+
const webReadableStream = nodeStreamToWebStream(nodeReadStream);
|
|
25
|
+
return new Response(webReadableStream, { status: status, headers: headers });
|
|
26
|
+
}
|
|
27
|
+
async function getFileSize(filePath) {
|
|
28
|
+
const stat = await fs.stat(filePath);
|
|
29
|
+
return stat.size;
|
|
30
|
+
}
|
|
31
|
+
function getFileStat(filePath) {
|
|
32
|
+
return fs.stat(filePath);
|
|
33
|
+
}
|
|
34
|
+
//endregion
|
|
35
|
+
function getMimeTypeFromName(fileName) {
|
|
36
|
+
const found = lookup(fileName);
|
|
37
|
+
if (found === false)
|
|
38
|
+
return "";
|
|
39
|
+
return found;
|
|
40
|
+
}
|
|
2
41
|
export function patch_fs() {
|
|
3
42
|
NodeSpace.fs = {
|
|
4
|
-
mkDir: (dirPath) => fs.mkdir(dirPath, { recursive: true })
|
|
43
|
+
mkDir: (dirPath) => fs.mkdir(dirPath, { recursive: true }),
|
|
44
|
+
fileURLToPath: (url) => fileURLToPath(url),
|
|
45
|
+
pathToFileURL: (fsPath) => pathToFileURL(fsPath),
|
|
46
|
+
getFileSize,
|
|
47
|
+
getMimeTypeFromName,
|
|
48
|
+
writeResponseToFile,
|
|
49
|
+
createResponseFromFile,
|
|
50
|
+
getFileStat
|
|
5
51
|
};
|
|
52
|
+
if (isBunJs()) {
|
|
53
|
+
NodeSpace.fs.fileURLToPath = (url) => Bun.fileURLToPath(url);
|
|
54
|
+
NodeSpace.fs.pathToFileURL = (fsPath) => Bun.pathToFileURL(fsPath);
|
|
55
|
+
NodeSpace.fs.writeResponseToFile = async (r, p) => { await Bun.file(p).write(r); };
|
|
56
|
+
NodeSpace.fs.createResponseFromFile = (filePath, status, headers) => {
|
|
57
|
+
return new Response(Bun.file(filePath), { status, headers });
|
|
58
|
+
};
|
|
59
|
+
}
|
|
6
60
|
}
|
|
7
61
|
//# sourceMappingURL=_fs_s.js.map
|
package/dist/_fs_s.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_fs_s.js","sourceRoot":"","sources":["../src/_fs_s.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"_fs_s.js","sourceRoot":"","sources":["../src/_fs_s.ts"],"names":[],"mappings":"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"}
|
package/dist/_term.js
CHANGED
|
@@ -3,6 +3,7 @@ const T_BOLD = "\x1b[1m";
|
|
|
3
3
|
const T_UNDERLINE = "\x1b[4m";
|
|
4
4
|
const T_CLEAR_LINE = "\x1b[2K";
|
|
5
5
|
const T_CLEAR_LINE_END = "\x1b[K";
|
|
6
|
+
const T_REWRITE_LINE = "\r\x1B[1F\x1B[1F\x1b[K";
|
|
6
7
|
const T_CLEAR_SCREEN = "\x1b[2J";
|
|
7
8
|
const T_LINE_START = "\r";
|
|
8
9
|
const C_RED = "\x1b[31m";
|
|
@@ -57,6 +58,7 @@ export function init_term() {
|
|
|
57
58
|
T_BOLD,
|
|
58
59
|
T_CLEAR_SCREEN,
|
|
59
60
|
T_UNDERLINE,
|
|
61
|
+
T_REWRITE_LINE,
|
|
60
62
|
T_CLEAR_LINE,
|
|
61
63
|
T_CLEAR_LINE_END,
|
|
62
64
|
T_LINE_START,
|
|
@@ -64,7 +66,18 @@ export function init_term() {
|
|
|
64
66
|
return params.join("") + T_RESET;
|
|
65
67
|
},
|
|
66
68
|
cssText,
|
|
67
|
-
moveUp, moveDown, moveLeft, moveRight, goAt
|
|
69
|
+
moveUp, moveDown, moveLeft, moveRight, goAt,
|
|
70
|
+
consoleLogErasable: (erase, ...args) => {
|
|
71
|
+
if (erase) {
|
|
72
|
+
let first = args.shift();
|
|
73
|
+
if (first)
|
|
74
|
+
first = "" + first;
|
|
75
|
+
console.log("\r\x1B[1F\x1B[1F\x1b[K" + first, ...args);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
console.log(...args);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
68
81
|
};
|
|
69
82
|
}
|
|
70
83
|
//# sourceMappingURL=_term.js.map
|
package/dist/_term.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_term.js","sourceRoot":"","sources":["../src/_term.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,SAAS,CAAC;AAE1B,MAAM,MAAM,GAAG,SAAS,CAAC;AACzB,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,MAAM,YAAY,GAAG,SAAS,CAAC;AAC/B,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAClC,MAAM,cAAc,GAAG,SAAS,CAAC;AACjC,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,YAAY,GAAG,UAAU,CAAC;AAChC,MAAM,OAAO,GAAG,UAAU,CAAC;AAC3B,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,MAAM,OAAO,GAAG,UAAU,CAAC;AAC3B,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,OAAO,GAAG,UAAU,CAAC;AAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC;AAC5B,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,SAAS,GAAG,UAAU,CAAC;AAC7B,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,OAAO,GAAG,UAAU,CAAC;AAE3B,SAAS,OAAO,CAAC,IAAY,EAAE,GAAW;IACtC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,GAAG,CAAC,CAAA;AACjC,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACrB,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACvB,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACvB,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IACxB,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,IAAI,CAAC,CAAS,EAAE,CAAS;IAC9B,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,SAAS;IACrB,SAAS,CAAC,IAAI,GAAG;QACb,KAAK;QACL,OAAO;QACP,MAAM;QACN,YAAY;QACZ,MAAM;QACN,QAAQ;QAER,OAAO;QACP,MAAM;QACN,MAAM;QACN,OAAO;QACP,SAAS;QACT,KAAK;QACL,OAAO;QACP,QAAQ;QAER,OAAO;QACP,MAAM;QACN,cAAc;QACd,WAAW;QACX,YAAY;QACZ,gBAAgB;QAChB,YAAY;QAEZ,QAAQ,CAAC,GAAG,MAAgB;YACxB,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC;QACrC,CAAC;QAED,OAAO;QAEP,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"_term.js","sourceRoot":"","sources":["../src/_term.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,SAAS,CAAC;AAE1B,MAAM,MAAM,GAAG,SAAS,CAAC;AACzB,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,MAAM,YAAY,GAAG,SAAS,CAAC;AAC/B,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAClC,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAChD,MAAM,cAAc,GAAG,SAAS,CAAC;AACjC,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,YAAY,GAAG,UAAU,CAAC;AAChC,MAAM,OAAO,GAAG,UAAU,CAAC;AAC3B,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,MAAM,OAAO,GAAG,UAAU,CAAC;AAC3B,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,OAAO,GAAG,UAAU,CAAC;AAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC;AAC5B,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,SAAS,GAAG,UAAU,CAAC;AAC7B,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,OAAO,GAAG,UAAU,CAAC;AAE3B,SAAS,OAAO,CAAC,IAAY,EAAE,GAAW;IACtC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,GAAG,CAAC,CAAA;AACjC,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACrB,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACvB,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACvB,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,SAAS,CAAC,CAAS;IACxB,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC;AAC7B,CAAC;AAED,SAAS,IAAI,CAAC,CAAS,EAAE,CAAS;IAC9B,OAAO,OAAO,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,SAAS;IACrB,SAAS,CAAC,IAAI,GAAG;QACb,KAAK;QACL,OAAO;QACP,MAAM;QACN,YAAY;QACZ,MAAM;QACN,QAAQ;QAER,OAAO;QACP,MAAM;QACN,MAAM;QACN,OAAO;QACP,SAAS;QACT,KAAK;QACL,OAAO;QACP,QAAQ;QAER,OAAO;QACP,MAAM;QACN,cAAc;QACd,WAAW;QACX,cAAc;QACd,YAAY;QACZ,gBAAgB;QAChB,YAAY;QAEZ,QAAQ,CAAC,GAAG,MAAgB;YACxB,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC;QACrC,CAAC;QAED,OAAO;QAEP,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI;QAE3C,kBAAkB,EAAE,CAAC,KAAc,EAAE,GAAG,IAAe,EAAE,EAAE;YACvD,IAAI,KAAK,EAAE,CAAC;gBACR,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;gBACzB,IAAI,KAAK;oBAAE,KAAK,GAAG,EAAE,GAAG,KAAK,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;YAC3D,CAAC;iBACI,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;KAEJ,CAAA;AACL,CAAC"}
|
package/dist/_timer.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { TimerCallback } from "./__global.ts";
|
|
1
2
|
export declare const ONE_SECOND = 1000;
|
|
2
3
|
export declare const ONE_MINUTE: number;
|
|
3
4
|
export declare const ONE_HOUR: number;
|
|
4
5
|
export declare const ONE_DAY: number;
|
|
5
|
-
export type TimerCallback = () => void | boolean | Promise<void | boolean>;
|
|
6
6
|
export declare function newInterval(durationInMs: number, callback: TimerCallback): void;
|
|
7
7
|
export declare function deferred(callback: () => void): void;
|
|
8
8
|
export declare function tick(timeInMs: number): Promise<void>;
|
package/dist/_timer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_timer.js","sourceRoot":"","sources":["../src/_timer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"_timer.js","sourceRoot":"","sources":["../src/_timer.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC;AAC/B,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,GAAG,EAAE,CAAC;AAC1C,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,GAAG,EAAE,CAAC;AAErC,MAAM,cAAc,GAA+C,EAAE,CAAC;AAEtE,MAAM,UAAU,WAAW,CAAC,YAAoB,EAAE,QAAuB;IACrE,IAAI,KAAK,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;IAEzC,IAAI,KAAK,EAAE,CAAC;QACR,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,OAAO;IACX,CAAC;IAED,cAAc,CAAC,YAAY,CAAC,GAAG,KAAK,GAAG,CAAC,QAAQ,CAAC,CAAC;IAElD,MAAM,MAAM,GAAG,KAAK,CAAC;IAErB,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACnC,KAAK,IAAI,CAAC,GAAC,CAAC,EAAE,CAAC,GAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,YAAY,OAAO;gBAAE,CAAC,GAAG,MAAM,CAAC,CAAC;YAEtC,yDAAyD;YACzD,IAAI,CAAC,KAAG,KAAK,EAAE,CAAC;gBACZ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACpB,CAAC,EAAE,CAAC;YACR,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACjB,aAAa,CAAC,OAAO,CAAC,CAAC;YACvB,OAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;QACzC,CAAC;IAEL,CAAC,EAAE,YAAY,CAAC,CAAC;IAEjB,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE;QAC3B,aAAa,CAAC,OAAO,CAAC,CAAC;QACvB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAkB;IACvC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,QAAgB;IACjC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,mBAAmB;IAC/B,SAAS,CAAC,KAAK,GAAG;QACd,UAAU;QACV,UAAU;QACV,QAAQ;QACR,OAAO;QAEP,IAAI;QACJ,WAAW;QACX,QAAQ;KACX,CAAC;AACN,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.0.
|
|
2
|
+
"version": "0.0.6",
|
|
3
3
|
"private": false,
|
|
4
4
|
"name": "jopi-node-space",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/johanpiquet/jopi-node-space",
|
|
7
|
-
|
|
8
7
|
"keywords": [],
|
|
9
8
|
"author": "Johan PIQUET",
|
|
10
9
|
"description": "An helper for hybrid apps",
|
|
11
|
-
|
|
12
10
|
"type": "module",
|
|
13
11
|
"main": "dist/index.js",
|
|
14
12
|
"types": "dist/index.d.ts",
|
|
15
13
|
|
|
16
14
|
"devDependencies": {
|
|
15
|
+
"@types/bun": "latest",
|
|
17
16
|
"@types/node": "latest",
|
|
18
|
-
"@types/
|
|
17
|
+
"@types/mime-types": "latest"
|
|
19
18
|
},
|
|
20
19
|
|
|
21
20
|
"scripts": {
|
|
22
21
|
"bun-install": "bun install",
|
|
23
22
|
"tsc": "tsc",
|
|
24
|
-
|
|
25
23
|
"npm-publish": "npm publish",
|
|
26
24
|
"bun link": "bun link"
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"mime-types": "^3.0.1"
|
|
27
29
|
}
|
|
28
|
-
}
|
|
30
|
+
}
|
package/src/__global.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import {deferred, ONE_DAY, ONE_HOUR, ONE_MINUTE, ONE_SECOND, type TimerCallback} from "./_timer";
|
|
2
|
-
|
|
3
1
|
declare global {
|
|
4
2
|
var NodeSpace: NodeSpaceType;
|
|
5
3
|
var jopiHotReload: HotReloadType;
|
|
@@ -26,7 +24,7 @@ export interface NodeSpaceType {
|
|
|
26
24
|
|
|
27
25
|
// >>> Server side only
|
|
28
26
|
|
|
29
|
-
fs
|
|
27
|
+
fs: FileSystemImpl;
|
|
30
28
|
|
|
31
29
|
// >>> Tools
|
|
32
30
|
|
|
@@ -63,6 +61,8 @@ interface ProcessImpl {
|
|
|
63
61
|
isProduction: boolean;
|
|
64
62
|
}
|
|
65
63
|
|
|
64
|
+
export type TimerCallback = () => void|boolean|Promise<void|boolean>;
|
|
65
|
+
|
|
66
66
|
interface TimerImpl {
|
|
67
67
|
ONE_SECOND: number,
|
|
68
68
|
ONE_MINUTE: number,
|
|
@@ -74,8 +74,29 @@ interface TimerImpl {
|
|
|
74
74
|
deferred: (callback: ()=>void) => void;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
export interface FileState {
|
|
78
|
+
size: number,
|
|
79
|
+
|
|
80
|
+
mtimeMs: number,
|
|
81
|
+
ctimeMs: number,
|
|
82
|
+
birthtimeMs: number,
|
|
83
|
+
|
|
84
|
+
isDirectory: () => boolean,
|
|
85
|
+
isFile: () => boolean,
|
|
86
|
+
isSymbolicLink: () => boolean,
|
|
87
|
+
}
|
|
88
|
+
|
|
77
89
|
interface FileSystemImpl {
|
|
78
90
|
mkDir: (dirPath: string) => Promise<string | undefined>;
|
|
91
|
+
fileURLToPath: (url: string) => string;
|
|
92
|
+
pathToFileURL: (fsPath: string) => URL;
|
|
93
|
+
|
|
94
|
+
getMimeTypeFromName: (fileName: string) => string;
|
|
95
|
+
getFileSize: (filePath: string) => Promise<number>;
|
|
96
|
+
getFileStat: (filePath: string) => Promise<FileState>;
|
|
97
|
+
|
|
98
|
+
writeResponseToFile: (response: Response, filePath: string) => Promise<void>;
|
|
99
|
+
createResponseFromFile: (filePath: string, status?: number, headers?: {[key: string]: string}|Headers) => Response;
|
|
79
100
|
}
|
|
80
101
|
|
|
81
102
|
interface AppImpl {
|
|
@@ -117,6 +138,7 @@ interface TerminalImpl {
|
|
|
117
138
|
T_RESET: string;
|
|
118
139
|
T_BOLD: string;
|
|
119
140
|
T_UNDERLINE: string;
|
|
141
|
+
T_REWRITE_LINE: string;
|
|
120
142
|
T_CLEAR_LINE: string;
|
|
121
143
|
T_CLEAR_LINE_END: string;
|
|
122
144
|
T_CLEAR_SCREEN: string;
|
|
@@ -138,6 +160,11 @@ interface TerminalImpl {
|
|
|
138
160
|
B_CYAN: string;
|
|
139
161
|
B_WHITE: string;
|
|
140
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Do a console.log, but replace the current line or add a new one.
|
|
165
|
+
*/
|
|
166
|
+
consoleLogErasable: (erase: boolean, ...args: unknown[])=>void;
|
|
167
|
+
|
|
141
168
|
colorize(...params: string[]): string;
|
|
142
169
|
cssText(text: string, css: string): void;
|
|
143
170
|
|
package/src/_fs_s.ts
CHANGED
|
@@ -1,7 +1,73 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
+
import {fileURLToPath} from "url";
|
|
3
|
+
import {isBunJs} from "./common.ts";
|
|
4
|
+
import {pathToFileURL} from "node:url";
|
|
5
|
+
import { lookup } from "mime-types";
|
|
6
|
+
import type {Readable} from "node:stream";
|
|
7
|
+
import {createReadStream} from "node:fs";
|
|
8
|
+
import type {FileState} from "./__global.ts";
|
|
9
|
+
|
|
10
|
+
//region NodeJS adapter
|
|
11
|
+
|
|
12
|
+
async function writeResponseToFile(response: Response, filePath: string) {
|
|
13
|
+
const bufferDonnees = await response.arrayBuffer();
|
|
14
|
+
const bufferNode = Buffer.from(bufferDonnees);
|
|
15
|
+
await fs.writeFile(filePath, bufferNode);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function nodeStreamToWebStream(nodeStream: Readable): ReadableStream {
|
|
19
|
+
return new ReadableStream({
|
|
20
|
+
start(controller) {
|
|
21
|
+
nodeStream.on('data', (chunk: Buffer) => { controller.enqueue(chunk) });
|
|
22
|
+
nodeStream.on('end', () => { controller.close() });
|
|
23
|
+
nodeStream.on('error', (err) => { controller.error(err) });
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function createResponseFromFile(filePath: string, status: number = 200, headers?: {[key: string]: string}|Headers): Response {
|
|
29
|
+
const nodeReadStream = createReadStream(filePath);
|
|
30
|
+
const webReadableStream = nodeStreamToWebStream(nodeReadStream);
|
|
31
|
+
return new Response(webReadableStream, {status: status, headers: headers});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function getFileSize(filePath: string): Promise<number> {
|
|
35
|
+
const stat = await fs.stat(filePath);
|
|
36
|
+
return stat.size;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getFileStat(filePath: string): Promise<FileState> {
|
|
40
|
+
return fs.stat(filePath);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//endregion
|
|
44
|
+
|
|
45
|
+
function getMimeTypeFromName(fileName: string) {
|
|
46
|
+
const found = lookup(fileName);
|
|
47
|
+
if (found===false) return "";
|
|
48
|
+
return found;
|
|
49
|
+
}
|
|
2
50
|
|
|
3
51
|
export function patch_fs() {
|
|
4
52
|
NodeSpace.fs = {
|
|
5
|
-
mkDir: (dirPath: string) => fs.mkdir(dirPath, {recursive: true})
|
|
53
|
+
mkDir: (dirPath: string) => fs.mkdir(dirPath, {recursive: true}),
|
|
54
|
+
fileURLToPath: (url) => fileURLToPath(url),
|
|
55
|
+
pathToFileURL: (fsPath) => pathToFileURL(fsPath),
|
|
56
|
+
|
|
57
|
+
getFileSize,
|
|
58
|
+
getMimeTypeFromName,
|
|
59
|
+
writeResponseToFile,
|
|
60
|
+
createResponseFromFile,
|
|
61
|
+
getFileStat
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (isBunJs()) {
|
|
65
|
+
NodeSpace.fs.fileURLToPath = (url) => Bun.fileURLToPath(url);
|
|
66
|
+
NodeSpace.fs.pathToFileURL = (fsPath) => Bun.pathToFileURL(fsPath);
|
|
67
|
+
NodeSpace.fs.writeResponseToFile = async (r: Response, p: string) => { await Bun.file(p).write(r); }
|
|
68
|
+
|
|
69
|
+
NodeSpace.fs.createResponseFromFile = (filePath, status, headers) => {
|
|
70
|
+
return new Response(Bun.file(filePath), {status, headers});
|
|
71
|
+
}
|
|
6
72
|
}
|
|
7
73
|
}
|
package/src/_term.ts
CHANGED
|
@@ -5,6 +5,7 @@ const T_UNDERLINE = "\x1b[4m";
|
|
|
5
5
|
|
|
6
6
|
const T_CLEAR_LINE = "\x1b[2K";
|
|
7
7
|
const T_CLEAR_LINE_END = "\x1b[K";
|
|
8
|
+
const T_REWRITE_LINE = "\r\x1B[1F\x1B[1F\x1b[K";
|
|
8
9
|
const T_CLEAR_SCREEN = "\x1b[2J";
|
|
9
10
|
const T_LINE_START = "\r";
|
|
10
11
|
|
|
@@ -70,6 +71,7 @@ export function init_term() {
|
|
|
70
71
|
T_BOLD,
|
|
71
72
|
T_CLEAR_SCREEN,
|
|
72
73
|
T_UNDERLINE,
|
|
74
|
+
T_REWRITE_LINE,
|
|
73
75
|
T_CLEAR_LINE,
|
|
74
76
|
T_CLEAR_LINE_END,
|
|
75
77
|
T_LINE_START,
|
|
@@ -80,7 +82,18 @@ export function init_term() {
|
|
|
80
82
|
|
|
81
83
|
cssText,
|
|
82
84
|
|
|
83
|
-
moveUp, moveDown, moveLeft, moveRight, goAt
|
|
85
|
+
moveUp, moveDown, moveLeft, moveRight, goAt,
|
|
86
|
+
|
|
87
|
+
consoleLogErasable: (erase: boolean, ...args: unknown[]) => {
|
|
88
|
+
if (erase) {
|
|
89
|
+
let first = args.shift();
|
|
90
|
+
if (first) first = "" + first;
|
|
91
|
+
console.log("\r\x1B[1F\x1B[1F\x1b[K" + first, ...args);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log(...args);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
84
97
|
|
|
85
98
|
}
|
|
86
99
|
}
|
package/src/_timer.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import type {TimerCallback} from "./__global.ts";
|
|
2
|
+
|
|
1
3
|
export const ONE_SECOND = 1000;
|
|
2
4
|
export const ONE_MINUTE = ONE_SECOND * 60;
|
|
3
5
|
export const ONE_HOUR = ONE_MINUTE * 60;
|
|
4
6
|
export const ONE_DAY = ONE_HOUR * 24;
|
|
5
7
|
|
|
6
|
-
export type TimerCallback = () => void|boolean|Promise<void|boolean>;
|
|
7
|
-
|
|
8
8
|
const timerListeners: {[timerDuration: number]: TimerCallback[]} = {};
|
|
9
9
|
|
|
10
10
|
export function newInterval(durationInMs: number, callback: TimerCallback) {
|