pinokiod 7.3.14 → 7.4.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/kernel/api/index.js +111 -15
- package/kernel/api/script/index.js +10 -0
- package/kernel/autolaunch.js +111 -0
- package/kernel/environment.js +89 -1
- package/kernel/git.js +9 -19
- package/kernel/index.js +142 -43
- package/kernel/launch_requirements.js +1115 -0
- package/kernel/ready.js +231 -0
- package/kernel/script.js +16 -0
- package/kernel/shells.js +9 -1
- package/kernel/workspace_status.js +111 -45
- package/package.json +1 -1
- package/server/autolaunch.js +725 -0
- package/server/index.js +244 -411
- package/server/public/logs.js +15 -1
- package/server/public/style.css +99 -31
- package/server/views/app.ejs +263 -159
- package/server/views/autolaunch.ejs +363 -75
- package/server/views/index.ejs +550 -26
- package/server/views/logs.ejs +14 -12
- package/server/views/partials/app_autolaunch_dependency_events.ejs +99 -0
- package/server/views/partials/app_autolaunch_dependency_save.ejs +10 -0
- package/server/views/partials/app_autolaunch_dependency_styles.ejs +357 -0
- package/server/views/partials/app_autolaunch_modal_helpers.ejs +347 -0
- package/server/views/partials/autolaunch_dependency_helpers.ejs +204 -0
- package/server/views/partials/autolaunch_dependency_save.ejs +13 -0
- package/server/views/partials/autolaunch_dependency_styles.ejs +347 -0
- package/server/views/partials/home_action_modal.ejs +4 -1
- package/server/views/partials/launch_requirements_status_client.ejs +271 -0
- package/server/views/partials/launch_requirements_status_styles.ejs +171 -0
- package/server/views/partials/launch_settings_dependency_save_factory.ejs +45 -0
- package/server/views/partials/launch_settings_dependency_script_loader_factory.ejs +25 -0
- package/server/views/terminal.ejs +196 -2
- package/test/home-autolaunch-live-ui.test.js +455 -0
- package/test/launch-requirements-browser.test.js +579 -0
- package/test/launch-requirements-contract-coverage.test.js +627 -0
- package/test/launch-requirements-real-browser.js +625 -0
- package/test/launch-requirements-status-client.test.js +132 -0
- package/test/launch-requirements.test.js +1806 -0
- package/test/launch-settings-ui.test.js +370 -0
- package/test/ready-state.test.js +49 -0
- package/test/server-autolaunch.test.js +1052 -0
- package/test/startup-git-index-benchmark.js +409 -0
- package/test/startup-git-index-browser.js +320 -0
- package/test/startup-git-index-performance.test.js +380 -0
- package/test/startup-git-index-refactor.test.js +450 -0
- package/test/startup-git-index-route.test.js +588 -0
- package/test/universal-launcher.smoke.spec.js +10 -9
- package/test/workspace-gitignore-benchmark.js +815 -0
- package/test/workspace-gitignore-path-scoped.test.js +256 -0
- package/spec/INSTRUCTION_SYNC.md +0 -432
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const assert = require("node:assert/strict")
|
|
2
|
+
const fs = require("node:fs/promises")
|
|
3
|
+
const path = require("node:path")
|
|
4
|
+
const test = require("node:test")
|
|
5
|
+
const ejs = require("ejs")
|
|
6
|
+
const { JSDOM } = require("jsdom")
|
|
7
|
+
|
|
8
|
+
const root = path.resolve(__dirname, "..")
|
|
9
|
+
const statusClientPath = path.resolve(root, "server/views/partials/launch_requirements_status_client.ejs")
|
|
10
|
+
|
|
11
|
+
async function renderStatusClient() {
|
|
12
|
+
const template = await fs.readFile(statusClientPath, "utf8")
|
|
13
|
+
return ejs.render(template, {
|
|
14
|
+
name: "target",
|
|
15
|
+
config: { title: "Target" },
|
|
16
|
+
launch_requirements_status_enabled: true
|
|
17
|
+
}, {
|
|
18
|
+
filename: statusClientPath
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function jsonResponse(payload, status = 200) {
|
|
23
|
+
return {
|
|
24
|
+
ok: status >= 200 && status < 300,
|
|
25
|
+
json: async () => payload
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function waitFor(predicate, message = "condition") {
|
|
30
|
+
const deadline = Date.now() + 2000
|
|
31
|
+
while (Date.now() < deadline) {
|
|
32
|
+
if (predicate()) return
|
|
33
|
+
await new Promise((resolve) => setTimeout(resolve, 20))
|
|
34
|
+
}
|
|
35
|
+
assert.fail(`Timed out waiting for ${message}`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
test("launch requirements stop clears local status instead of rendering a stopped acknowledgement", async () => {
|
|
39
|
+
const script = await renderStatusClient()
|
|
40
|
+
const status = {
|
|
41
|
+
state: "waiting",
|
|
42
|
+
requirements: [
|
|
43
|
+
{
|
|
44
|
+
id: "helper",
|
|
45
|
+
title: "Helper",
|
|
46
|
+
state: "starting",
|
|
47
|
+
script: "start.js",
|
|
48
|
+
icon: "/pinokio-black.png"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "middle",
|
|
52
|
+
title: "Middle",
|
|
53
|
+
state: "waiting",
|
|
54
|
+
waiting_for: ["helper"],
|
|
55
|
+
icon: "/pinokio-black.png"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let socketCallback = null
|
|
61
|
+
let cancelPosts = 0
|
|
62
|
+
let refreshCalls = 0
|
|
63
|
+
const dom = new JSDOM(`<!doctype html>
|
|
64
|
+
<main>
|
|
65
|
+
<div data-launch-requirements-status hidden></div>
|
|
66
|
+
</main>
|
|
67
|
+
<script>${script}</script>
|
|
68
|
+
`, {
|
|
69
|
+
url: "http://127.0.0.1/app",
|
|
70
|
+
runScripts: "dangerously",
|
|
71
|
+
pretendToBeVisual: true,
|
|
72
|
+
beforeParse(window) {
|
|
73
|
+
window.Socket = function Socket() {
|
|
74
|
+
this.run = function run(_options, callback) {
|
|
75
|
+
socketCallback = callback
|
|
76
|
+
return Promise.resolve()
|
|
77
|
+
}
|
|
78
|
+
this.close = function close() {}
|
|
79
|
+
}
|
|
80
|
+
window.refresh = function refresh() {
|
|
81
|
+
refreshCalls += 1
|
|
82
|
+
}
|
|
83
|
+
window.fetch = async function fetch(url, options = {}) {
|
|
84
|
+
if (String(url).includes("/cancel") && options.method === "POST") {
|
|
85
|
+
cancelPosts += 1
|
|
86
|
+
return jsonResponse({ ok: true, cancelled: true })
|
|
87
|
+
}
|
|
88
|
+
return jsonResponse({ ok: true, status })
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const { document } = dom.window
|
|
94
|
+
const statusRoot = document.querySelector("[data-launch-requirements-status]")
|
|
95
|
+
await waitFor(() => statusRoot.textContent.includes("Preparing required apps"), "initial preparation render")
|
|
96
|
+
|
|
97
|
+
document.querySelector("[data-launch-requirements-stop]").click()
|
|
98
|
+
await waitFor(() => statusRoot.hidden === true, "status card to clear")
|
|
99
|
+
|
|
100
|
+
assert.equal(cancelPosts, 1)
|
|
101
|
+
assert.equal(refreshCalls, 1)
|
|
102
|
+
assert.equal(statusRoot.hidden, true)
|
|
103
|
+
assert.doesNotMatch(statusRoot.textContent, /Launch stopped/)
|
|
104
|
+
assert.doesNotMatch(statusRoot.textContent, /Stopped/)
|
|
105
|
+
|
|
106
|
+
socketCallback({
|
|
107
|
+
type: "launch.requirements",
|
|
108
|
+
data: { status: null }
|
|
109
|
+
})
|
|
110
|
+
await new Promise((resolve) => setTimeout(resolve, 20))
|
|
111
|
+
assert.equal(statusRoot.hidden, true)
|
|
112
|
+
assert.doesNotMatch(statusRoot.textContent, /Launch stopped/)
|
|
113
|
+
|
|
114
|
+
socketCallback({
|
|
115
|
+
type: "launch.requirements",
|
|
116
|
+
data: {
|
|
117
|
+
status: {
|
|
118
|
+
state: "waiting",
|
|
119
|
+
requirements: [{
|
|
120
|
+
id: "other",
|
|
121
|
+
title: "Other",
|
|
122
|
+
state: "starting",
|
|
123
|
+
script: "other.js"
|
|
124
|
+
}]
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
await waitFor(() => statusRoot.textContent.includes("Preparing required apps"), "new status replaces acknowledgement")
|
|
129
|
+
|
|
130
|
+
assert.doesNotMatch(statusRoot.textContent, /Launch stopped/)
|
|
131
|
+
assert.match(statusRoot.textContent, /Other/)
|
|
132
|
+
})
|