@artian-techs/adonis-orbit 0.1.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/LICENSE.md +21 -0
- package/README.md +275 -0
- package/build/configure.d.ts +8 -0
- package/build/configure.js +38 -0
- package/build/index.d.ts +10 -0
- package/build/index.js +9 -0
- package/build/providers/orbit_provider.d.ts +13 -0
- package/build/providers/orbit_provider.js +35 -0
- package/build/src/auth/basic_auth.d.ts +12 -0
- package/build/src/auth/basic_auth.js +36 -0
- package/build/src/controllers/dashboard_controller.d.ts +51 -0
- package/build/src/controllers/dashboard_controller.js +341 -0
- package/build/src/define_config.d.ts +5 -0
- package/build/src/define_config.js +6 -0
- package/build/src/jobs/prune_job_runs.d.ts +20 -0
- package/build/src/jobs/prune_job_runs.js +27 -0
- package/build/src/logo.d.ts +4 -0
- package/build/src/logo.js +12 -0
- package/build/src/middleware/dashboard_auth.d.ts +10 -0
- package/build/src/middleware/dashboard_auth.js +16 -0
- package/build/src/models/job_run.d.ts +35 -0
- package/build/src/models/job_run.js +71 -0
- package/build/src/models/silenced_job.d.ts +14 -0
- package/build/src/models/silenced_job.js +27 -0
- package/build/src/recorder.d.ts +14 -0
- package/build/src/recorder.js +102 -0
- package/build/src/retry.d.ts +9 -0
- package/build/src/retry.js +18 -0
- package/build/src/routes.d.ts +8 -0
- package/build/src/routes.js +20 -0
- package/build/src/sinks/database_sink.d.ts +16 -0
- package/build/src/sinks/database_sink.js +88 -0
- package/build/src/types.d.ts +92 -0
- package/build/src/types.js +1 -0
- package/build/stubs/config/orbit.stub +31 -0
- package/build/stubs/main.d.ts +1 -0
- package/build/stubs/main.js +1 -0
- package/build/stubs/migrations/create_job_runs_table.stub +62 -0
- package/build/stubs/migrations/create_silenced_jobs_table.stub +29 -0
- package/build/templates/components/layout.edge +174 -0
- package/build/templates/index.edge +111 -0
- package/build/templates/metrics.edge +59 -0
- package/build/templates/orbit.svg +35 -0
- package/build/templates/silenced.edge +35 -0
- package/package.json +130 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
@component('orbit::components/layout', { title, active, menu, path, logo, favicon, theme })
|
|
2
|
+
@if(showStats)
|
|
3
|
+
<div class="cards">
|
|
4
|
+
<div class="card">
|
|
5
|
+
<div class="value">{{ stats.perMinute }}</div>
|
|
6
|
+
<div class="label">Jobs per minute</div>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="card">
|
|
9
|
+
<div class="value">{{ stats.pastHour }}</div>
|
|
10
|
+
<div class="label">Jobs past hour</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="card">
|
|
13
|
+
<div class="value">{{ stats.failedPastWeek }}</div>
|
|
14
|
+
<div class="label">Failed jobs past 7 days</div>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="card">
|
|
17
|
+
<div class="value">{{ stats.running }}</div>
|
|
18
|
+
<div class="label">Jobs running now</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<h2>Recent jobs</h2>
|
|
23
|
+
@end
|
|
24
|
+
|
|
25
|
+
<div class="panel">
|
|
26
|
+
<table>
|
|
27
|
+
<thead>
|
|
28
|
+
<tr>
|
|
29
|
+
<th>Job</th>
|
|
30
|
+
<th>Status</th>
|
|
31
|
+
<th>Attempts</th>
|
|
32
|
+
<th>Duration</th>
|
|
33
|
+
<th>Dates</th>
|
|
34
|
+
<th>Details</th>
|
|
35
|
+
<th></th>
|
|
36
|
+
</tr>
|
|
37
|
+
</thead>
|
|
38
|
+
<tbody>
|
|
39
|
+
@each(row in rows)
|
|
40
|
+
<tr>
|
|
41
|
+
<td>
|
|
42
|
+
<b>{{ row.name }}</b>
|
|
43
|
+
<div class="muted">{{ row.queue }}</div>
|
|
44
|
+
<div class="muted">{{ row.jobId }}</div>
|
|
45
|
+
</td>
|
|
46
|
+
<td><span class="status {{ row.status }}">{{ row.statusLabel }}</span></td>
|
|
47
|
+
<td>{{ row.attempts }}</td>
|
|
48
|
+
<td>{{ row.duration ? row.duration + ' ms' : '—' }}</td>
|
|
49
|
+
<td class="muted">
|
|
50
|
+
@if(row.dispatchedAt)
|
|
51
|
+
<div>queued {{ row.dispatchedAt }}</div>
|
|
52
|
+
@end
|
|
53
|
+
@if(row.finishedAt)
|
|
54
|
+
<div>ended {{ row.finishedAt }}</div>
|
|
55
|
+
@end
|
|
56
|
+
@if(row.retriedAt)
|
|
57
|
+
<div>asked again {{ row.retriedAt }}</div>
|
|
58
|
+
@end
|
|
59
|
+
</td>
|
|
60
|
+
<td>
|
|
61
|
+
<details>
|
|
62
|
+
<summary>payload</summary>
|
|
63
|
+
<pre>{{ row.payload }}</pre>
|
|
64
|
+
</details>
|
|
65
|
+
@if(row.error)
|
|
66
|
+
<details>
|
|
67
|
+
<summary>error</summary>
|
|
68
|
+
<pre>{{ row.error }}</pre>
|
|
69
|
+
</details>
|
|
70
|
+
@end
|
|
71
|
+
</td>
|
|
72
|
+
<td>
|
|
73
|
+
<div class="actions">
|
|
74
|
+
@if(row.canRetry)
|
|
75
|
+
<form method="post" action="{{ path }}/runs/{{ row.id }}/retry">
|
|
76
|
+
@if(csrfToken)
|
|
77
|
+
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
|
|
78
|
+
@end
|
|
79
|
+
<button type="submit">Retry</button>
|
|
80
|
+
</form>
|
|
81
|
+
@elseif(row.retriedJobId)
|
|
82
|
+
<a class="muted" href="{{ path }}?job={{ row.retriedJobId }}">
|
|
83
|
+
asked again{{ row.retriedStatus ? ' — ' + row.retriedStatus : '' }}
|
|
84
|
+
</a>
|
|
85
|
+
@end
|
|
86
|
+
<form method="post" action="{{ path }}/jobs/{{ row.name }}/silence">
|
|
87
|
+
@if(csrfToken)
|
|
88
|
+
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
|
|
89
|
+
@end
|
|
90
|
+
<button type="submit">Silence</button>
|
|
91
|
+
</form>
|
|
92
|
+
</div>
|
|
93
|
+
</td>
|
|
94
|
+
</tr>
|
|
95
|
+
@else
|
|
96
|
+
<tr><td colspan="7" class="empty">No job yet.</td></tr>
|
|
97
|
+
@end
|
|
98
|
+
</tbody>
|
|
99
|
+
</table>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<div class="pager">
|
|
103
|
+
@if(page > 1)
|
|
104
|
+
<a href="{{ path }}?page={{ page - 1 }}&status={{ status }}">← Previous</a>
|
|
105
|
+
@end
|
|
106
|
+
<span class="muted">Page {{ page }} of {{ lastPage }} — {{ total }} job(s)</span>
|
|
107
|
+
@if(page < lastPage)
|
|
108
|
+
<a href="{{ path }}?page={{ page + 1 }}&status={{ status }}">Next →</a>
|
|
109
|
+
@end
|
|
110
|
+
</div>
|
|
111
|
+
@end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
@component('orbit::components/layout', { title, active, menu, path, logo, favicon, theme })
|
|
2
|
+
<p class="muted">What each class and each queue cost over the last {{ hours }} hours.</p>
|
|
3
|
+
|
|
4
|
+
<h2>By job</h2>
|
|
5
|
+
<div class="panel">
|
|
6
|
+
<table>
|
|
7
|
+
<thead>
|
|
8
|
+
<tr>
|
|
9
|
+
<th>Job</th>
|
|
10
|
+
<th>Ended</th>
|
|
11
|
+
<th>Failed</th>
|
|
12
|
+
<th>Average</th>
|
|
13
|
+
<th>Longest</th>
|
|
14
|
+
</tr>
|
|
15
|
+
</thead>
|
|
16
|
+
<tbody>
|
|
17
|
+
@each(row in byJob)
|
|
18
|
+
<tr>
|
|
19
|
+
<td><b>{{ row.label }}</b></td>
|
|
20
|
+
<td>{{ row.total }}</td>
|
|
21
|
+
<td>{{ row.failed }}</td>
|
|
22
|
+
<td>{{ row.average === null ? '—' : row.average + ' ms' }}</td>
|
|
23
|
+
<td>{{ row.longest === null ? '—' : row.longest + ' ms' }}</td>
|
|
24
|
+
</tr>
|
|
25
|
+
@else
|
|
26
|
+
<tr><td colspan="5" class="empty">No job ended in this window.</td></tr>
|
|
27
|
+
@end
|
|
28
|
+
</tbody>
|
|
29
|
+
</table>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<h2>By queue</h2>
|
|
33
|
+
<div class="panel">
|
|
34
|
+
<table>
|
|
35
|
+
<thead>
|
|
36
|
+
<tr>
|
|
37
|
+
<th>Queue</th>
|
|
38
|
+
<th>Ended</th>
|
|
39
|
+
<th>Failed</th>
|
|
40
|
+
<th>Average</th>
|
|
41
|
+
<th>Longest</th>
|
|
42
|
+
</tr>
|
|
43
|
+
</thead>
|
|
44
|
+
<tbody>
|
|
45
|
+
@each(row in byQueue)
|
|
46
|
+
<tr>
|
|
47
|
+
<td><b>{{ row.label }}</b></td>
|
|
48
|
+
<td>{{ row.total }}</td>
|
|
49
|
+
<td>{{ row.failed }}</td>
|
|
50
|
+
<td>{{ row.average === null ? '—' : row.average + ' ms' }}</td>
|
|
51
|
+
<td>{{ row.longest === null ? '—' : row.longest + ' ms' }}</td>
|
|
52
|
+
</tr>
|
|
53
|
+
@else
|
|
54
|
+
<tr><td colspan="5" class="empty">No job ended in this window.</td></tr>
|
|
55
|
+
@end
|
|
56
|
+
</tbody>
|
|
57
|
+
</table>
|
|
58
|
+
</div>
|
|
59
|
+
@end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="19.58 29.17 100.83 88.83">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="orbit-primary" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
4
|
+
<stop offset="0%" stop-color="#6366F1"/>
|
|
5
|
+
<stop offset="50%" stop-color="#8B5CF6"/>
|
|
6
|
+
<stop offset="100%" stop-color="#D946EF"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
|
|
9
|
+
<linearGradient id="orbit-accent" x1="0%" y1="0%" x2="100%" y2="0%">
|
|
10
|
+
<stop offset="0%" stop-color="#06B6D4"/>
|
|
11
|
+
<stop offset="100%" stop-color="#3B82F6"/>
|
|
12
|
+
</linearGradient>
|
|
13
|
+
|
|
14
|
+
<filter id="soft-shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
15
|
+
<feDropShadow dx="0" dy="4" stdDeviation="6" flood-color="#6366F1" flood-opacity="0.25"/>
|
|
16
|
+
</filter>
|
|
17
|
+
</defs>
|
|
18
|
+
|
|
19
|
+
<g transform="translate(10, 10)">
|
|
20
|
+
<!-- Anneau secondaire (arrière-plan) -->
|
|
21
|
+
<ellipse cx="60" cy="60" rx="50" ry="20" fill="none" stroke="url(#orbit-accent)" stroke-width="3.5" transform="rotate(-30 60 60)" opacity="0.7"/>
|
|
22
|
+
|
|
23
|
+
<!-- Anneau principal (complet et continu) -->
|
|
24
|
+
<ellipse cx="60" cy="60" rx="52" ry="22" fill="none" stroke="url(#orbit-primary)" stroke-width="5" transform="rotate(35 60 60)" filter="url(#soft-shadow)"/>
|
|
25
|
+
|
|
26
|
+
<!-- Noyau central -->
|
|
27
|
+
<circle cx="60" cy="60" r="14" fill="url(#orbit-primary)"/>
|
|
28
|
+
<circle cx="60" cy="60" r="6" fill="#FFFFFF" opacity="0.9"/>
|
|
29
|
+
|
|
30
|
+
<!-- Jobs / Workers en orbite -->
|
|
31
|
+
<circle cx="102" cy="38" r="6" fill="#06B6D4" filter="url(#soft-shadow)"/>
|
|
32
|
+
<circle cx="18" cy="82" r="5" fill="#D946EF"/>
|
|
33
|
+
<circle cx="78" cy="104" r="4" fill="#3B82F6"/>
|
|
34
|
+
</g>
|
|
35
|
+
</svg>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
@component('orbit::components/layout', { title, active, menu, path, logo, favicon, theme })
|
|
2
|
+
<p class="muted" style="max-width: 640px">
|
|
3
|
+
These job classes are left out of the lists. Their work goes on and their
|
|
4
|
+
trace is written. Take a name away, and everything it did comes back,
|
|
5
|
+
including what it did while it was silent.
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<div class="panel">
|
|
9
|
+
<table>
|
|
10
|
+
<thead>
|
|
11
|
+
<tr>
|
|
12
|
+
<th>Job</th>
|
|
13
|
+
<th></th>
|
|
14
|
+
</tr>
|
|
15
|
+
</thead>
|
|
16
|
+
<tbody>
|
|
17
|
+
@each(name in names)
|
|
18
|
+
<tr>
|
|
19
|
+
<td><b>{{ name }}</b></td>
|
|
20
|
+
<td>
|
|
21
|
+
<form method="post" action="{{ path }}/jobs/{{ name }}/silence">
|
|
22
|
+
@if(csrfToken)
|
|
23
|
+
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
|
|
24
|
+
@end
|
|
25
|
+
<button type="submit">Show again</button>
|
|
26
|
+
</form>
|
|
27
|
+
</td>
|
|
28
|
+
</tr>
|
|
29
|
+
@else
|
|
30
|
+
<tr><td colspan="2" class="empty">No job is silenced.</td></tr>
|
|
31
|
+
@end
|
|
32
|
+
</tbody>
|
|
33
|
+
</table>
|
|
34
|
+
</div>
|
|
35
|
+
@end
|
package/package.json
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@artian-techs/adonis-orbit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "See what the queue of AdonisJS does, keep it, and ask a job again.",
|
|
6
|
+
"main": "build/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./build/index.js",
|
|
9
|
+
"./types": "./build/src/types.js",
|
|
10
|
+
"./orbit_provider": "./build/providers/orbit_provider.js",
|
|
11
|
+
"./stubs/*": "./build/stubs/*"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"build/index.js",
|
|
15
|
+
"build/index.d.ts",
|
|
16
|
+
"build/configure.js",
|
|
17
|
+
"build/configure.d.ts",
|
|
18
|
+
"build/src",
|
|
19
|
+
"build/providers",
|
|
20
|
+
"build/stubs",
|
|
21
|
+
"build/templates",
|
|
22
|
+
"LICENSE.md",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "pnpm run compile",
|
|
27
|
+
"clean": "del-cli build",
|
|
28
|
+
"compile": "pnpm run clean && tsc",
|
|
29
|
+
"copy:templates": "cpy \"stubs/**/*.stub\" build/stubs && cpy \"templates/**/*.{edge,svg}\" build/templates",
|
|
30
|
+
"postcompile": "pnpm run copy:templates",
|
|
31
|
+
"test": "node --enable-source-maps --import=@poppinss/ts-exec bin/test.ts",
|
|
32
|
+
"preview": "node --enable-source-maps --import=@poppinss/ts-exec bin/preview.ts",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"lint": "eslint .",
|
|
35
|
+
"format": "prettier --write .",
|
|
36
|
+
"checks": "pnpm lint && pnpm typecheck",
|
|
37
|
+
"prepublishOnly": "pnpm run build",
|
|
38
|
+
"release": "release-it"
|
|
39
|
+
},
|
|
40
|
+
"prettier": "@adonisjs/prettier-config",
|
|
41
|
+
"keywords": [
|
|
42
|
+
"adonisjs",
|
|
43
|
+
"queue",
|
|
44
|
+
"jobs",
|
|
45
|
+
"dashboard"
|
|
46
|
+
],
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"author": {
|
|
49
|
+
"name": "Oussama Benhamed",
|
|
50
|
+
"email": "b.oussama@corposmart.dz"
|
|
51
|
+
},
|
|
52
|
+
"homepage": "https://github.com/artian-techs/adonis-orbit#readme",
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "git+https://github.com/artian-techs/adonis-orbit.git"
|
|
56
|
+
},
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/artian-techs/adonis-orbit/issues"
|
|
59
|
+
},
|
|
60
|
+
"packageManager": "pnpm@10.24.0",
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=24.0.0"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"@adonisjs/assembler": "^7.0.0 || ^8.0.0",
|
|
66
|
+
"@adonisjs/core": "^6.18.0 || ^7.0.0",
|
|
67
|
+
"@adonisjs/lucid": "^21.0.0 || ^22.0.0",
|
|
68
|
+
"@adonisjs/queue": "^0.6.0",
|
|
69
|
+
"edge.js": "^6.0.0",
|
|
70
|
+
"luxon": "^3.0.0"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@adonisjs/assembler": "^8.5.0",
|
|
74
|
+
"@adonisjs/core": "^7.4.0",
|
|
75
|
+
"@adonisjs/eslint-config": "^3.1.0",
|
|
76
|
+
"@adonisjs/lucid": "^22.4.2",
|
|
77
|
+
"@adonisjs/prettier-config": "^1.5.0",
|
|
78
|
+
"@adonisjs/queue": "^0.6.2",
|
|
79
|
+
"@adonisjs/tsconfig": "^2.0.0",
|
|
80
|
+
"@japa/assert": "^4.2.0",
|
|
81
|
+
"@japa/runner": "^5.3.0",
|
|
82
|
+
"@poppinss/ts-exec": "^1.4.4",
|
|
83
|
+
"@release-it/conventional-changelog": "^12.0.0",
|
|
84
|
+
"@types/luxon": "^3.7.4",
|
|
85
|
+
"@types/node": "^24.13.3",
|
|
86
|
+
"@types/pg": "^8.23.1",
|
|
87
|
+
"cpy-cli": "^5.0.0",
|
|
88
|
+
"del-cli": "^6.0.0",
|
|
89
|
+
"edge.js": "^6.0.2",
|
|
90
|
+
"eslint": "^10.8.1",
|
|
91
|
+
"luxon": "^3.5.0",
|
|
92
|
+
"pg": "^8.23.0",
|
|
93
|
+
"prettier": "^3.9.6",
|
|
94
|
+
"release-it": "^21.0.2",
|
|
95
|
+
"typescript": "^6.0.3"
|
|
96
|
+
},
|
|
97
|
+
"peerDependenciesMeta": {
|
|
98
|
+
"@adonisjs/assembler": {
|
|
99
|
+
"optional": true
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"publishConfig": {
|
|
103
|
+
"access": "public",
|
|
104
|
+
"tag": "latest"
|
|
105
|
+
},
|
|
106
|
+
"release-it": {
|
|
107
|
+
"git": {
|
|
108
|
+
"requireCleanWorkingDir": true,
|
|
109
|
+
"requireUpstream": true,
|
|
110
|
+
"commitMessage": "chore(release): ${version}",
|
|
111
|
+
"tagAnnotation": "v${version}",
|
|
112
|
+
"push": true,
|
|
113
|
+
"tagName": "v${version}"
|
|
114
|
+
},
|
|
115
|
+
"github": {
|
|
116
|
+
"release": true
|
|
117
|
+
},
|
|
118
|
+
"npm": {
|
|
119
|
+
"publish": true,
|
|
120
|
+
"skipChecks": true
|
|
121
|
+
},
|
|
122
|
+
"plugins": {
|
|
123
|
+
"@release-it/conventional-changelog": {
|
|
124
|
+
"preset": {
|
|
125
|
+
"name": "angular"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|