@qtoggle/qui 1.18.2 → 1.19.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/.github/workflows/main.yml +8 -4
- package/js/index.js +17 -2
- package/js/utils/debouncer.js +44 -0
- package/package.json +1 -1
- package/pyproject.toml +2 -3
- package/webpack/webpack-common.js +5 -6
|
@@ -5,7 +5,7 @@ on: push
|
|
|
5
5
|
jobs:
|
|
6
6
|
lint:
|
|
7
7
|
name: Lint
|
|
8
|
-
runs-on:
|
|
8
|
+
runs-on: self-hosted
|
|
9
9
|
steps:
|
|
10
10
|
- name: Lint JS Code
|
|
11
11
|
uses: qtoggle/actions-common/actions/lint-js@v1
|
|
@@ -16,7 +16,7 @@ jobs:
|
|
|
16
16
|
jsdoc:
|
|
17
17
|
name: Publish Docs
|
|
18
18
|
if: startsWith(github.ref, 'refs/tags/version-')
|
|
19
|
-
runs-on:
|
|
19
|
+
runs-on: self-hosted
|
|
20
20
|
needs:
|
|
21
21
|
- lint
|
|
22
22
|
steps:
|
|
@@ -24,6 +24,10 @@ jobs:
|
|
|
24
24
|
uses: actions/checkout@v4
|
|
25
25
|
- name: Replace source version
|
|
26
26
|
uses: qtoggle/actions-common/actions/replace-source-version@v1
|
|
27
|
+
- name: Setup NodeJS
|
|
28
|
+
uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: '18'
|
|
27
31
|
- name: Install
|
|
28
32
|
run: |
|
|
29
33
|
npm install && rm -rf docs/* js/lib/* && npx jsdoc -c jsdoc.conf.json
|
|
@@ -35,14 +39,14 @@ jobs:
|
|
|
35
39
|
FOLDER: docs
|
|
36
40
|
build-python:
|
|
37
41
|
name: Build Python
|
|
38
|
-
runs-on:
|
|
42
|
+
runs-on: self-hosted
|
|
39
43
|
steps:
|
|
40
44
|
- name: Build Python package
|
|
41
45
|
uses: qtoggle/actions-common/actions/build-python-package@v1
|
|
42
46
|
publish:
|
|
43
47
|
name: Publish
|
|
44
48
|
if: startsWith(github.ref, 'refs/tags/version-')
|
|
45
|
-
runs-on:
|
|
49
|
+
runs-on: self-hosted
|
|
46
50
|
needs:
|
|
47
51
|
- lint
|
|
48
52
|
- jsdoc
|
package/js/index.js
CHANGED
|
@@ -44,6 +44,8 @@ const logger = Logger.get('qui')
|
|
|
44
44
|
*/
|
|
45
45
|
export let whenReady = new ConditionVariable()
|
|
46
46
|
|
|
47
|
+
let globalErrorMessageForm = null
|
|
48
|
+
|
|
47
49
|
|
|
48
50
|
function initConfig() {
|
|
49
51
|
/* Look for the main script name */
|
|
@@ -177,6 +179,11 @@ function configureGlobalErrorHandling() {
|
|
|
177
179
|
return
|
|
178
180
|
}
|
|
179
181
|
|
|
182
|
+
/* Don't show another global error message on top of an existing one */
|
|
183
|
+
if (globalErrorMessageForm != null) {
|
|
184
|
+
return
|
|
185
|
+
}
|
|
186
|
+
|
|
180
187
|
logger.error(`unhandled promise rejection: ${e.reason || '<unspecified reason>'}`)
|
|
181
188
|
if (e.reason != null) {
|
|
182
189
|
logger.error(e.reason)
|
|
@@ -186,8 +193,16 @@ function configureGlobalErrorHandling() {
|
|
|
186
193
|
let msg = gettext('An unexpected error occurred.')
|
|
187
194
|
msg += '<br>'
|
|
188
195
|
msg += gettext('Application reloading is recommended.')
|
|
189
|
-
new StickySimpleMessageForm(
|
|
190
|
-
|
|
196
|
+
globalErrorMessageForm = new StickySimpleMessageForm(
|
|
197
|
+
{
|
|
198
|
+
type: 'error',
|
|
199
|
+
message: msg,
|
|
200
|
+
onClose: function () {
|
|
201
|
+
globalErrorMessageForm = null
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
globalErrorMessageForm.show()
|
|
191
206
|
})
|
|
192
207
|
}
|
|
193
208
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* A class that debounces function calls, ensuring that a function is not called more often than a specified delay.
|
|
4
|
+
* @alias qui.utils.Debouncer
|
|
5
|
+
*/
|
|
6
|
+
class Debouncer {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @constructs
|
|
10
|
+
* @param {Function} func the function to debounce
|
|
11
|
+
* @param {Number} delay the debouncing delay, in milliseconds
|
|
12
|
+
*/
|
|
13
|
+
constructor(func, delay) {
|
|
14
|
+
this._func = func
|
|
15
|
+
this._delay = delay
|
|
16
|
+
this._timeoutHandle = null
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Call function ensuring debouncing condition. Any previous pending call is cancelled.
|
|
21
|
+
* Arguments are passed to the function when called.
|
|
22
|
+
*/
|
|
23
|
+
call(...args) {
|
|
24
|
+
if (this._timeoutHandle !== null) {
|
|
25
|
+
clearTimeout(this._timeoutHandle)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this._timeoutHandle = setTimeout(function () {
|
|
29
|
+
this._timeoutHandle = null
|
|
30
|
+
this._func(...args)
|
|
31
|
+
}.bind(this), this._delay)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Tell if there is a pending call.
|
|
36
|
+
* @return {Boolean}
|
|
37
|
+
*/
|
|
38
|
+
isPending() {
|
|
39
|
+
return this._timeoutHandle != null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default Debouncer
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "qui-server"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.19.0"
|
|
4
4
|
description = "A fully fledged qToggle implementation written in Python"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Calin Crisan", email = "ccrisan@gmail.com"},
|
|
7
7
|
]
|
|
8
|
-
requires-python = "
|
|
8
|
+
requires-python = ">=3.11"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "Apache 2.0"}
|
|
11
11
|
dependencies = [
|
|
@@ -28,7 +28,6 @@ package = true
|
|
|
28
28
|
|
|
29
29
|
[tool.ruff]
|
|
30
30
|
line-length = 120
|
|
31
|
-
target-version = "py310"
|
|
32
31
|
lint.extend-select = ["I", "RUF022"]
|
|
33
32
|
lint.isort.lines-after-imports = 2
|
|
34
33
|
lint.isort.lines-between-types = 1
|
|
@@ -210,7 +210,7 @@ function makeJSRule({type, appFullPath}) {
|
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
function makeConfig({theme, isProduction, appName, appFullPath,
|
|
213
|
+
function makeConfig({theme, isProduction, appName, appFullPath, extraAliases, cssOnly}) {
|
|
214
214
|
/* QUI is assumed to live in `node_modules` */
|
|
215
215
|
let quiFullPath = path.resolve(__dirname, '..')
|
|
216
216
|
|
|
@@ -255,8 +255,6 @@ function makeConfig({theme, isProduction, appName, appFullPath, extraFiles, cssO
|
|
|
255
255
|
...requireFromDir(TMPL_REGEX, appTmplPath)
|
|
256
256
|
]
|
|
257
257
|
|
|
258
|
-
// TODO add extraFiles to requirements
|
|
259
|
-
|
|
260
258
|
let mainEntryName = `${appName}-bundle`
|
|
261
259
|
let shellCommands = []
|
|
262
260
|
let entries = {}
|
|
@@ -279,7 +277,8 @@ function makeConfig({theme, isProduction, appName, appFullPath, extraFiles, cssO
|
|
|
279
277
|
alias: {
|
|
280
278
|
$qui: quiJSPath,
|
|
281
279
|
$app: appJSPath,
|
|
282
|
-
$node: nodeJSPath
|
|
280
|
+
$node: nodeJSPath,
|
|
281
|
+
...extraAliases
|
|
283
282
|
}
|
|
284
283
|
},
|
|
285
284
|
output: {
|
|
@@ -359,7 +358,7 @@ function makeConfig({theme, isProduction, appName, appFullPath, extraFiles, cssO
|
|
|
359
358
|
}
|
|
360
359
|
}
|
|
361
360
|
|
|
362
|
-
function makeConfigs({isProduction, appName, appFullPath,
|
|
361
|
+
function makeConfigs({isProduction, appName, appFullPath, extraAliases}) {
|
|
363
362
|
/* Repeat the configuration for each theme, but only build JS once, the first time */
|
|
364
363
|
|
|
365
364
|
return THEMES.map((theme, i) => makeConfig({
|
|
@@ -367,7 +366,7 @@ function makeConfigs({isProduction, appName, appFullPath, extraFiles}) {
|
|
|
367
366
|
isProduction: isProduction,
|
|
368
367
|
appName: appName,
|
|
369
368
|
appFullPath: appFullPath,
|
|
370
|
-
|
|
369
|
+
extraAliases: extraAliases,
|
|
371
370
|
cssOnly: i > 0
|
|
372
371
|
}))
|
|
373
372
|
}
|