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 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
  }
@@ -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?: FileSystemImpl;
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
@@ -1,3 +1,3 @@
1
- import { deferred, ONE_DAY, ONE_HOUR, ONE_MINUTE, ONE_SECOND } from "./_timer";
2
1
  globalThis.NodeSpace = {};
2
+ export {};
3
3
  //# sourceMappingURL=__global.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"__global.js","sourceRoot":"","sources":["../src/__global.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAqB,MAAM,UAAU,CAAC;AAOjG,UAAU,CAAC,SAAS,GAAG,EAAmB,CAAC"}
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;AAElC,MAAM,UAAU,QAAQ;IACpB,SAAS,CAAC,EAAE,GAAG;QACX,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC;KACnE,CAAA;AACL,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;KAE9C,CAAA;AACL,CAAC"}
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>;
@@ -1 +1 @@
1
- {"version":3,"file":"_timer.js","sourceRoot":"","sources":["../src/_timer.ts"],"names":[],"mappings":"AAAA,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;AAIrC,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"}
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.4",
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/bun": "latest"
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?: FileSystemImpl;
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) {