@lobb-js/studio 0.5.0 → 0.7.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.
- package/dist/components/LlmButton.svelte +3 -1
- package/dist/components/Studio.svelte +78 -98
- package/dist/components/Studio.svelte.d.ts +1 -1
- package/dist/components/breadCrumbs.svelte +0 -1
- package/dist/components/combobox.svelte +3 -3
- package/dist/components/confirmationDialog/confirmationDialog.svelte +1 -1
- package/dist/components/createManyButton.svelte +3 -1
- package/dist/components/dataTable/childRecords.svelte +4 -2
- package/dist/components/dataTable/dataTable.svelte +6 -3
- package/dist/components/dataTable/fieldCell.svelte +6 -3
- package/dist/components/dataTable/filter.svelte +4 -2
- package/dist/components/dataTable/filterButton.svelte +1 -1
- package/dist/components/dataTable/header.svelte +3 -1
- package/dist/components/dataTable/sort.svelte +5 -3
- package/dist/components/dataTable/sortButton.svelte +2 -2
- package/dist/components/dataTable/utils.d.ts +7 -6
- package/dist/components/dataTable/utils.js +14 -13
- package/dist/components/detailView/create/children.svelte +5 -3
- package/dist/components/detailView/create/createDetailView.svelte +14 -10
- package/dist/components/detailView/create/createDetailViewButton.svelte +15 -10
- package/dist/components/detailView/create/createDetailViewButton.svelte.d.ts +1 -1
- package/dist/components/detailView/create/createManyView.svelte +8 -6
- package/dist/components/detailView/create/subRecords.svelte +3 -1
- package/dist/components/detailView/fieldInput.svelte +7 -5
- package/dist/components/detailView/fieldInputReplacement.svelte +1 -1
- package/dist/components/detailView/store.svelte.d.ts +3 -2
- package/dist/components/detailView/store.svelte.js +11 -14
- package/dist/components/detailView/update/children.svelte +6 -4
- package/dist/components/detailView/update/updateDetailView.svelte +11 -9
- package/dist/components/detailView/update/updateDetailViewButton.svelte +35 -11
- package/dist/components/detailView/update/updateDetailViewButton.svelte.d.ts +1 -1
- package/dist/components/detailView/utils.d.ts +6 -5
- package/dist/components/detailView/utils.js +9 -10
- package/dist/components/extensionsComponents.svelte +4 -1
- package/dist/components/miniSidebar.svelte +9 -21
- package/dist/components/rangeCalendarButton.svelte +3 -3
- package/dist/components/routes/collections/collection.svelte +8 -6
- package/dist/components/routes/collections/collections.svelte +5 -3
- package/dist/components/routes/data_model/dataModel.svelte +2 -2
- package/dist/components/routes/data_model/flow.svelte +3 -1
- package/dist/components/routes/data_model/syncManager.svelte +7 -5
- package/dist/components/routes/extensions/extension.svelte +5 -2
- package/dist/components/routes/home.svelte +4 -2
- package/dist/components/routes/workflows/workflows.svelte +9 -7
- package/dist/components/selectRecord.svelte +5 -1
- package/dist/components/setServerPage.svelte +4 -2
- package/dist/components/singletone.svelte +4 -2
- package/dist/components/ui/alert-dialog/alert-dialog-action.svelte +1 -1
- package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte +1 -1
- package/dist/components/ui/command/command-dialog.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-day.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-day.svelte.d.ts +1 -1
- package/dist/components/ui/range-calendar/range-calendar-next-button.svelte +1 -1
- package/dist/components/ui/range-calendar/range-calendar-prev-button.svelte +1 -1
- package/dist/components/ui/select/select-separator.svelte +1 -1
- package/dist/components/workflowEditor.svelte +6 -4
- package/dist/context.d.ts +10 -0
- package/dist/context.js +11 -0
- package/dist/eventSystem.d.ts +2 -1
- package/dist/eventSystem.js +7 -7
- package/dist/extensions/extensionUtils.d.ts +7 -6
- package/dist/extensions/extensionUtils.js +17 -60
- package/dist/store.svelte.d.ts +1 -3
- package/dist/store.svelte.js +19 -36
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +2 -3
- package/package.json +6 -2
- package/vite-plugins/index.d.ts +8 -0
- package/vite-plugins/index.js +4 -9
- package/vite-plugins/lobb-extensions.js +73 -0
- package/vite-plugins/monorepo-workspace.js +138 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
// Generates a virtual module `virtual:lobb-studio-extensions` that:
|
|
5
|
+
// 1. Reads the consumer project's package.json
|
|
6
|
+
// 2. Finds all @lobb-js/lobb-ext-* deps that have a ./studio subpath export
|
|
7
|
+
// 3. Statically imports them as a name->factory map
|
|
8
|
+
// 4. Also globs local extension studio entry points
|
|
9
|
+
// Result: { "auth": authFactory, "storage": storageFactory, "myext": localFactory }
|
|
10
|
+
export function lobbExtensionsPlugin() {
|
|
11
|
+
const virtualModuleId = "virtual:lobb-studio-extensions";
|
|
12
|
+
const resolvedVirtualModuleId = "\0" + virtualModuleId;
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
name: "lobb-studio-extensions",
|
|
16
|
+
resolveId(id) {
|
|
17
|
+
if (id === virtualModuleId) return resolvedVirtualModuleId;
|
|
18
|
+
},
|
|
19
|
+
load(id) {
|
|
20
|
+
if (id !== resolvedVirtualModuleId) return;
|
|
21
|
+
|
|
22
|
+
let pkg;
|
|
23
|
+
try {
|
|
24
|
+
pkg = JSON.parse(readFileSync(resolve(process.cwd(), "package.json"), "utf-8"));
|
|
25
|
+
} catch {
|
|
26
|
+
return `export default {};`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
30
|
+
|
|
31
|
+
// Find @lobb-js/lobb-ext-* packages that have a ./studio export
|
|
32
|
+
const extPackages = [];
|
|
33
|
+
for (const pkgName of Object.keys(deps)) {
|
|
34
|
+
if (!pkgName.startsWith("@lobb-js/lobb-ext-")) continue;
|
|
35
|
+
try {
|
|
36
|
+
const pkgJsonPath = resolve(process.cwd(), "node_modules", pkgName, "package.json");
|
|
37
|
+
const extPkg = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
|
|
38
|
+
if (extPkg.exports?.["./studio"]) {
|
|
39
|
+
const name = pkgName.replace("@lobb-js/lobb-ext-", "");
|
|
40
|
+
extPackages.push({ name, pkgName });
|
|
41
|
+
}
|
|
42
|
+
} catch {}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const imports = extPackages
|
|
46
|
+
.map(({ name, pkgName }) => `import ext_${name} from "${pkgName}/studio";`)
|
|
47
|
+
.join("\n");
|
|
48
|
+
|
|
49
|
+
const mapEntries = extPackages
|
|
50
|
+
.map(({ name }) => ` "${name}": ext_${name}`)
|
|
51
|
+
.join(",\n");
|
|
52
|
+
|
|
53
|
+
return `${imports}
|
|
54
|
+
|
|
55
|
+
const localModules = import.meta.glob('/extensions/*/studio/index.ts', { eager: true });
|
|
56
|
+
const localExtensions = Object.fromEntries(
|
|
57
|
+
Object.entries(localModules)
|
|
58
|
+
.map(([path, mod]) => {
|
|
59
|
+
const name = path.match(/\\/extensions\\/([^\\/]+)\\/studio/)?.[1];
|
|
60
|
+
return [name, mod.default];
|
|
61
|
+
})
|
|
62
|
+
.filter(([name]) => name != null)
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const npmExtensions = {
|
|
66
|
+
${mapEntries}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default { ...npmExtensions, ...localExtensions };
|
|
70
|
+
`;
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { readdirSync, lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
2
|
+
import { join, resolve, dirname } from "node:path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Auto-detects workspace-linked @lobb-js/* packages and configures Vite so
|
|
6
|
+
* that monorepo dev and standalone npm-install users both work without manual
|
|
7
|
+
* configuration:
|
|
8
|
+
*
|
|
9
|
+
* - exclude: Prevents vite-plugin-svelte's optimize-module from
|
|
10
|
+
* running esbuild on raw .svelte source files.
|
|
11
|
+
* - entries: Tells Vite to crawl workspace packages at startup so
|
|
12
|
+
* all their deps are discovered and pre-bundled upfront
|
|
13
|
+
* (avoids 504 timeouts on first browser load).
|
|
14
|
+
* - include: Re-includes leaf CJS deps of excluded packages so
|
|
15
|
+
* Vite still pre-bundles them for the browser.
|
|
16
|
+
* - holdUntilCrawlEnd: Blocks the first response until optimization is done.
|
|
17
|
+
* - server.fs.allow: Allows Vite to serve files from the monorepo root
|
|
18
|
+
* (needed to follow symlinks into workspace packages).
|
|
19
|
+
*
|
|
20
|
+
* For standalone users (real npm install, no symlinks) all lists are empty and
|
|
21
|
+
* the config has no effect.
|
|
22
|
+
*
|
|
23
|
+
* @returns {import('vite').Plugin}
|
|
24
|
+
*/
|
|
25
|
+
export function lobbWorkspaceOptimize() {
|
|
26
|
+
return {
|
|
27
|
+
name: "lobb-workspace-optimize",
|
|
28
|
+
config(_, { command }) {
|
|
29
|
+
if (command !== "serve") return;
|
|
30
|
+
|
|
31
|
+
const workspacePkgs = getLobbWorkspacePackages();
|
|
32
|
+
if (workspacePkgs.length === 0) return;
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
optimizeDeps: {
|
|
36
|
+
holdUntilCrawlEnd: true,
|
|
37
|
+
entries: getWorkspaceEntries(workspacePkgs),
|
|
38
|
+
exclude: workspacePkgs,
|
|
39
|
+
include: getCjsDepsOf(workspacePkgs),
|
|
40
|
+
},
|
|
41
|
+
server: {
|
|
42
|
+
fs: {
|
|
43
|
+
allow: [getMonorepoRoot(workspacePkgs)].filter(Boolean),
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getLobbWorkspacePackages() {
|
|
52
|
+
const dir = resolve("node_modules/@lobb-js");
|
|
53
|
+
try {
|
|
54
|
+
return readdirSync(dir)
|
|
55
|
+
.filter((pkg) => lstatSync(join(dir, pkg)).isSymbolicLink())
|
|
56
|
+
.map((pkg) => `@lobb-js/${pkg}`);
|
|
57
|
+
} catch {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getMonorepoRoot(pkgNames) {
|
|
63
|
+
for (const name of pkgNames) {
|
|
64
|
+
try {
|
|
65
|
+
const realPath = realpathSync(resolve(`node_modules/${name}`));
|
|
66
|
+
// realPath is e.g. /root/lobb/packages/studio — go up to find the monorepo root
|
|
67
|
+
let dir = realPath;
|
|
68
|
+
for (let i = 0; i < 5; i++) {
|
|
69
|
+
const parent = dirname(dir);
|
|
70
|
+
if (parent === dir) break;
|
|
71
|
+
const pkgJson = tryReadJson(join(parent, "package.json"));
|
|
72
|
+
if (pkgJson?.workspaces) return parent;
|
|
73
|
+
dir = parent;
|
|
74
|
+
}
|
|
75
|
+
} catch { /* skip */ }
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function getWorkspaceEntries(pkgNames) {
|
|
81
|
+
const entries = [];
|
|
82
|
+
for (const name of pkgNames) {
|
|
83
|
+
try {
|
|
84
|
+
const realPath = realpathSync(resolve(`node_modules/${name}`));
|
|
85
|
+
const pkg = tryReadJson(join(realPath, "package.json"));
|
|
86
|
+
if (!pkg) continue;
|
|
87
|
+
const exportsField = pkg.exports;
|
|
88
|
+
const entry =
|
|
89
|
+
pkg.svelte ??
|
|
90
|
+
pkg.module ??
|
|
91
|
+
pkg.main ??
|
|
92
|
+
(typeof exportsField?.["."] === "string"
|
|
93
|
+
? exportsField["."]
|
|
94
|
+
: exportsField?.["."]?.default);
|
|
95
|
+
if (typeof entry === "string") entries.push(join(realPath, entry));
|
|
96
|
+
} catch { /* skip */ }
|
|
97
|
+
}
|
|
98
|
+
return entries;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function readPkgFrom(name, baseDir) {
|
|
102
|
+
let dir = baseDir;
|
|
103
|
+
for (let i = 0; i < 8; i++) {
|
|
104
|
+
const pkg = tryReadJson(join(dir, "node_modules", name, "package.json"));
|
|
105
|
+
if (pkg) return pkg;
|
|
106
|
+
const parent = dirname(dir);
|
|
107
|
+
if (parent === dir) break;
|
|
108
|
+
dir = parent;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function getCjsDepsOf(pkgNames) {
|
|
114
|
+
const deps = [];
|
|
115
|
+
for (const name of pkgNames) {
|
|
116
|
+
try {
|
|
117
|
+
const realPath = realpathSync(resolve(`node_modules/${name}`));
|
|
118
|
+
const pkg = tryReadJson(join(realPath, "package.json"));
|
|
119
|
+
if (!pkg) continue;
|
|
120
|
+
for (const dep of Object.keys(pkg.dependencies ?? {})) {
|
|
121
|
+
const depPkg = readPkgFrom(dep, realPath);
|
|
122
|
+
if (!depPkg) continue;
|
|
123
|
+
const isCjs = depPkg.type !== "module";
|
|
124
|
+
const isLeaf = Object.keys(depPkg.dependencies ?? {}).length === 0;
|
|
125
|
+
if (isCjs && isLeaf) deps.push(dep);
|
|
126
|
+
}
|
|
127
|
+
} catch { /* skip */ }
|
|
128
|
+
}
|
|
129
|
+
return [...new Set(deps)];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function tryReadJson(filePath) {
|
|
133
|
+
try {
|
|
134
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
135
|
+
} catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|