@mak-98/dirvi-app 0.0.0-stage → 0.11.0-beta.2

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 (78) hide show
  1. package/LICENSE +674 -0
  2. package/dist/application/create-dirvi-api.d.ts +10 -0
  3. package/dist/application/create-dirvi-api.d.ts.map +1 -0
  4. package/dist/application/create-dirvi-api.js +23 -0
  5. package/dist/application/init-runtime.d.ts +20 -0
  6. package/dist/application/init-runtime.d.ts.map +1 -0
  7. package/dist/application/init-runtime.js +117 -0
  8. package/dist/application/package-loader.d.ts +9 -0
  9. package/dist/application/package-loader.d.ts.map +1 -0
  10. package/dist/application/package-loader.js +1 -0
  11. package/dist/application/shell-api.d.ts +5 -0
  12. package/dist/application/shell-api.d.ts.map +1 -0
  13. package/dist/application/shell-api.js +1 -0
  14. package/dist/domain/app-pack-ref.d.ts +17 -0
  15. package/dist/domain/app-pack-ref.d.ts.map +1 -0
  16. package/dist/domain/app-pack-ref.js +37 -0
  17. package/dist/domain/app.d.ts +39 -0
  18. package/dist/domain/app.d.ts.map +1 -0
  19. package/dist/domain/app.js +25 -0
  20. package/dist/domain/config.d.ts +402 -0
  21. package/dist/domain/config.d.ts.map +1 -0
  22. package/dist/domain/config.js +44 -0
  23. package/dist/domain/dirvi-api.d.ts +24 -0
  24. package/dist/domain/dirvi-api.d.ts.map +1 -0
  25. package/dist/domain/dirvi-api.js +1 -0
  26. package/dist/domain/ex-command.d.ts +12 -0
  27. package/dist/domain/ex-command.d.ts.map +1 -0
  28. package/dist/domain/ex-command.js +1 -0
  29. package/dist/domain/init-runtime.d.ts +41 -0
  30. package/dist/domain/init-runtime.d.ts.map +1 -0
  31. package/dist/domain/init-runtime.js +1 -0
  32. package/dist/domain/initialization.d.ts +20 -0
  33. package/dist/domain/initialization.d.ts.map +1 -0
  34. package/dist/domain/initialization.js +1 -0
  35. package/dist/domain/public-init-api.d.ts +42 -0
  36. package/dist/domain/public-init-api.d.ts.map +1 -0
  37. package/dist/domain/public-init-api.js +1 -0
  38. package/dist/domain/shell-api.d.ts +5 -0
  39. package/dist/domain/shell-api.d.ts.map +1 -0
  40. package/dist/domain/shell-api.js +1 -0
  41. package/dist/domain/theme.d.ts +536 -0
  42. package/dist/domain/theme.d.ts.map +1 -0
  43. package/dist/domain/theme.js +170 -0
  44. package/dist/domain/view-name-schema.d.ts +18 -0
  45. package/dist/domain/view-name-schema.d.ts.map +1 -0
  46. package/dist/domain/view-name-schema.js +68 -0
  47. package/dist/index.d.ts +17 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +6 -0
  50. package/dist/theme.d.ts +536 -0
  51. package/dist/theme.d.ts.map +1 -0
  52. package/dist/theme.js +170 -0
  53. package/dist/ui/App.d.ts +18 -0
  54. package/dist/ui/App.d.ts.map +1 -0
  55. package/dist/ui/App.js +225 -0
  56. package/dist/ui/AppSetup.d.ts +17 -0
  57. package/dist/ui/AppSetup.d.ts.map +1 -0
  58. package/dist/ui/AppSetup.js +88 -0
  59. package/dist/ui/Shell.d.ts +37 -0
  60. package/dist/ui/Shell.d.ts.map +1 -0
  61. package/dist/ui/Shell.js +52 -0
  62. package/dist/ui/app-screen-renderer.d.ts +28 -0
  63. package/dist/ui/app-screen-renderer.d.ts.map +1 -0
  64. package/dist/ui/app-screen-renderer.js +1 -0
  65. package/dist/ui/color-resolver.d.ts +3 -0
  66. package/dist/ui/color-resolver.d.ts.map +1 -0
  67. package/dist/ui/color-resolver.js +61 -0
  68. package/dist/ui/hooks/useView.d.ts +4 -0
  69. package/dist/ui/hooks/useView.d.ts.map +1 -0
  70. package/dist/ui/hooks/useView.js +32 -0
  71. package/dist/ui/loading-screen-renderer.d.ts +3 -0
  72. package/dist/ui/loading-screen-renderer.d.ts.map +1 -0
  73. package/dist/ui/loading-screen-renderer.js +1 -0
  74. package/dist/ui/view.d.ts +23 -0
  75. package/dist/ui/view.d.ts.map +1 -0
  76. package/dist/ui/view.js +74 -0
  77. package/package.json +34 -3
  78. package/README.md +0 -3
@@ -0,0 +1,61 @@
1
+ const ansi16Colors = [
2
+ [0, 0, 0],
3
+ [205, 49, 49],
4
+ [13, 188, 121],
5
+ [229, 229, 16],
6
+ [36, 114, 200],
7
+ [188, 63, 188],
8
+ [17, 168, 205],
9
+ [229, 229, 229],
10
+ [102, 102, 102],
11
+ [241, 76, 76],
12
+ [35, 209, 139],
13
+ [245, 245, 67],
14
+ [59, 142, 234],
15
+ [214, 112, 214],
16
+ [41, 184, 219],
17
+ [255, 255, 255],
18
+ ];
19
+ export function colorConfigToInkColor(colorConfig, colorDepth = process.stderr.getColorDepth()) {
20
+ const { hex, ansi256, basic } = colorConfig;
21
+ if (colorDepth >= 24 && hex !== undefined) {
22
+ return hex;
23
+ }
24
+ if (colorDepth >= 8 && ansi256 !== undefined) {
25
+ return toHex(ansi256ToRgb(ansi256));
26
+ }
27
+ if (basic !== undefined) {
28
+ return basic;
29
+ }
30
+ // A more specific value was not configured. Let Ink/Chalk reduce the
31
+ // available richer value for the current terminal where necessary.
32
+ if (ansi256 !== undefined) {
33
+ return toHex(ansi256ToRgb(ansi256));
34
+ }
35
+ if (hex !== undefined) {
36
+ return hex;
37
+ }
38
+ // ColorConfigSchema guarantees at least one profile is configured.
39
+ throw new Error('Expected at least one terminal color profile');
40
+ }
41
+ function ansi256ToRgb(color) {
42
+ if (color < 16) {
43
+ return ansi16Colors[color];
44
+ }
45
+ if (color >= 232) {
46
+ const component = 8 + (color - 232) * 10;
47
+ return [component, component, component];
48
+ }
49
+ const cubeColor = color - 16;
50
+ const red = Math.floor(cubeColor / 36);
51
+ const green = Math.floor((cubeColor % 36) / 6);
52
+ const blue = cubeColor % 6;
53
+ const components = [0, 95, 135, 175, 215, 255];
54
+ return [components[red], components[green], components[blue]];
55
+ }
56
+ function toHex([red, green, blue]) {
57
+ return `#${toHexComponent(red)}${toHexComponent(green)}${toHexComponent(blue)}`;
58
+ }
59
+ function toHexComponent(component) {
60
+ return component.toString(16).padStart(2, '0');
61
+ }
@@ -0,0 +1,4 @@
1
+ import type { CursorApi, NavBranch, NavNodeApi, SerializableKey, State } from 'dirvi-lib';
2
+ import { View } from '../view.js';
3
+ export declare function useView<Id extends SerializableKey, Value>(navNode: NavBranch<Id>, state: State<Id, Value>, navNodeApi: NavNodeApi<Id, Value>, cursorApi: CursorApi<Id>, rowCount: number): View;
4
+ //# sourceMappingURL=useView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useView.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/useView.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,eAAe,EACf,KAAK,EACN,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,IAAI,EAAgB,MAAM,YAAY,CAAC;AAMhD,wBAAgB,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,KAAK,EACvD,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,EACtB,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,EACvB,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,EACjC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC,EACxB,QAAQ,EAAE,MAAM,GACf,IAAI,CAwBN"}
@@ -0,0 +1,32 @@
1
+ import { useRef } from 'react';
2
+ import { View } from '../view.js';
3
+ const STATUS_BAR_HEIGHT = 1;
4
+ // Hooks that keeps Ref of the viewport's start, and returns View sliced to
5
+ // only the rows that should be visible.
6
+ export function useView(navNode, state, navNodeApi, cursorApi, rowCount) {
7
+ const viewportStartRef = useRef(0);
8
+ const viewportHeight = Math.max(0, rowCount - STATUS_BAR_HEIGHT);
9
+ if (viewportHeight === 0) {
10
+ return { rows: [] };
11
+ }
12
+ const rows = View.createRows(navNode, navNodeApi, state.cursor, cursorApi);
13
+ viewportStartRef.current = viewportStart(rows, viewportHeight, viewportStartRef.current);
14
+ return View.create(navNode, navNodeApi, state.cursor, cursorApi, viewportHeight, viewportStartRef.current);
15
+ }
16
+ function viewportStart(rows, viewportHeight, currentViewportStart) {
17
+ const scrollMargin = 3;
18
+ const cursorIndex = rows.findIndex((row) => row.cursor);
19
+ const maximumViewportStart = Math.max(0, rows.length - viewportHeight);
20
+ let viewportStart = currentViewportStart;
21
+ if (cursorIndex >= 0) {
22
+ const firstVisibleCursorIndex = viewportStart + scrollMargin;
23
+ const lastVisibleCursorIndex = viewportStart + viewportHeight - 1 - scrollMargin;
24
+ if (cursorIndex < firstVisibleCursorIndex) {
25
+ viewportStart = cursorIndex - scrollMargin;
26
+ }
27
+ else if (cursorIndex > lastVisibleCursorIndex) {
28
+ viewportStart = cursorIndex - viewportHeight + 1 + scrollMargin;
29
+ }
30
+ }
31
+ return Math.max(0, Math.min(viewportStart, maximumViewportStart));
32
+ }
@@ -0,0 +1,3 @@
1
+ import type { ComponentType } from 'react';
2
+ export type LoadingScreenRenderer = ComponentType<{}>;
3
+ //# sourceMappingURL=loading-screen-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loading-screen-renderer.d.ts","sourceRoot":"","sources":["../../src/ui/loading-screen-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { Cursor, CursorApi, NavBranch, NavNodeApi, SerializableKey } from 'dirvi-lib';
2
+ type ViewRowBase = {
3
+ id: string;
4
+ indent: number;
5
+ content: string;
6
+ cursor: boolean;
7
+ selected: boolean;
8
+ };
9
+ export type ViewRow = (ViewRowBase & {
10
+ type: 'leaf';
11
+ }) | (ViewRowBase & {
12
+ type: 'branch';
13
+ foldedCount: number;
14
+ });
15
+ export type View = {
16
+ rows: ViewRow[];
17
+ };
18
+ export declare const View: {
19
+ createRows<Id extends SerializableKey, Value>(rootNode: NavBranch<Id>, navNodeApi: NavNodeApi<Id, Value>, cursor: Cursor<Id>, cursorApi: CursorApi<Id>): ViewRow[];
20
+ create<Id extends SerializableKey, Value>(rootNode: NavBranch<Id>, navNodeApi: NavNodeApi<Id, Value>, cursor: Cursor<Id>, cursorApi: CursorApi<Id>, viewportHeight: number, viewportStart: number): View;
21
+ };
22
+ export {};
23
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/ui/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,SAAS,EACT,SAAS,EAGT,UAAU,EACV,eAAe,EAChB,MAAM,WAAW,CAAC;AAEnB,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,OAAO,GACf,CAAC,WAAW,GAAG;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,GACF,CAAC,WAAW,GAAG;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEP,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,IAAI;eACJ,EAAE,SAAS,eAAe,EAAE,KAAK,YAChC,SAAS,CAAC,EAAE,CAAC,cACX,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,UACzB,MAAM,CAAC,EAAE,CAAC,aACP,SAAS,CAAC,EAAE,CAAC,GACvB,OAAO,EAAE;WAoBL,EAAE,SAAS,eAAe,EAAE,KAAK,YAC5B,SAAS,CAAC,EAAE,CAAC,cACX,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,UACzB,MAAM,CAAC,EAAE,CAAC,aACP,SAAS,CAAC,EAAE,CAAC,kBACR,MAAM,iBACP,MAAM,GACpB,IAAI;CAOR,CAAC"}
@@ -0,0 +1,74 @@
1
+ export const View = {
2
+ createRows(rootNode, navNodeApi, cursor, cursorApi) {
3
+ const rootCursor = [];
4
+ const rootRow = viewRowForEntry(rootNode, null, cursorApi.equal(cursor, rootCursor), navNodeApi);
5
+ if (rootNode.children === null) {
6
+ return [rootRow];
7
+ }
8
+ return [
9
+ rootRow,
10
+ ...viewRowsAtNode(rootNode.children, [], navNodeApi, cursor, cursorApi),
11
+ ];
12
+ },
13
+ create(rootNode, navNodeApi, cursor, cursorApi, viewportHeight, viewportStart) {
14
+ const rows = View.createRows(rootNode, navNodeApi, cursor, cursorApi);
15
+ return {
16
+ rows: rows.slice(viewportStart, viewportStart + viewportHeight),
17
+ };
18
+ },
19
+ };
20
+ /**
21
+ * Converts one NavNode and its descendants into display ViewRows.
22
+ *
23
+ * `node` is the directory currently being visited.
24
+ *
25
+ * `parentPath` is the path of that directory. For example:
26
+ *
27
+ * [] root directory
28
+ * ['src'] root/src
29
+ * ['src', 'lib'] root/src/lib
30
+ */
31
+ function viewRowsAtNode(node, parentPath, navNodeApi, cursor, cursorApi) {
32
+ const rows = [];
33
+ for (const entry of node.entries) {
34
+ const entryCursor = [...parentPath, entry.id];
35
+ const isCursor = cursorApi.equal(cursor, entryCursor);
36
+ rows.push(viewRowForEntry(entry, parentPath, isCursor, navNodeApi));
37
+ // Case where there's no branches
38
+ if (!navNodeApi.entryIsBranch(entry) || entry.children === null) {
39
+ continue;
40
+ }
41
+ rows.push(...viewRowsAtNode(entry.children, [...parentPath, entry.id], navNodeApi, cursor, cursorApi));
42
+ }
43
+ return rows;
44
+ }
45
+ function viewRowForEntry(entry, parentPath, cursor, navNodeApi) {
46
+ const id = entryId(parentPath ?? [], entry.id);
47
+ const indent = parentPath ? parentPath.length + 1 : 0;
48
+ const selected = false;
49
+ if (navNodeApi.entryIsBranch(entry)) {
50
+ const foldedCount = entry.children === null || entry.children.folded === null
51
+ ? 0
52
+ : entry.children.folded.entries.length;
53
+ return {
54
+ id,
55
+ indent,
56
+ selected,
57
+ cursor,
58
+ content: `${String(entry.id)}/`,
59
+ type: 'branch',
60
+ foldedCount,
61
+ };
62
+ }
63
+ return {
64
+ id,
65
+ indent,
66
+ selected,
67
+ cursor,
68
+ content: String(entry.id),
69
+ type: 'leaf',
70
+ };
71
+ }
72
+ function entryId(parentPath, entryName) {
73
+ return `entry:${JSON.stringify([...parentPath, entryName])}`;
74
+ }
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
1
  {
2
2
  "name": "@mak-98/dirvi-app",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.11.0-beta.2",
4
+ "description": "Shared React application logic for dirvi hosts.",
5
+ "type": "module",
6
+ "license": "GPL-3.0-or-later",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "dirvi-apis": "0.11.0-beta.2",
20
+ "dirvi-lib": "0.11.0-beta.2",
21
+ "zod": "^4.4.3"
22
+ },
23
+ "peerDependencies": {
24
+ "react": "^19.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^22.20.1",
28
+ "@types/react": "^19.0.0",
29
+ "react": "^19.0.0",
30
+ "typescript": "^5.0.0"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc -p tsconfig.json",
34
+ "typecheck": "tsc -p tsconfig.json --noEmit",
35
+ "format": "prettier . --write"
36
+ }
6
37
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.