Projektstart

This commit is contained in:
2026-01-22 15:49:12 +01:00
parent 7212eb6f7a
commit 57e5f652f8
10637 changed files with 2598792 additions and 64 deletions

View File

@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: '/'
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: npm
directory: '/'
schedule:
interval: daily
open-pull-requests-limit: 10

View File

@@ -0,0 +1,46 @@
name: CI
on:
push:
paths-ignore:
- 'docs/**'
- '*.md'
pull_request:
paths-ignore:
- 'docs/**'
- '*.md'
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [14, 16, 18, 20]
os: [macos-latest, ubuntu-latest, windows-latest]
exclude:
- node-version: 14
os: windows-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install
run: |
npm install --ignore-scripts
- name: Run tests
run: |
npm run test
automerge:
needs: test
runs-on: ubuntu-latest
steps:
- uses: fastify/github-action-merge-dependabot@v3.9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

21
backend/node_modules/on-exit-leak-free/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Matteo Collina
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

54
backend/node_modules/on-exit-leak-free/README.md generated vendored Normal file
View File

@@ -0,0 +1,54 @@
# on-exit-leak-free
This module helps dispose of an object gracefully when the Node.js process exits.
It executes a function with a given parameter
on [`'exit'`](https://nodejs.org/api/process.html#event-exit) without leaking memory,
cleaning things up appropriately if the object is garbage collected.
Requires `WeakRef` and `FinalizationRegistry`, i.e. use Node v14+.
## Install
```bash
npm i on-exit-leak-free
```
## Example
```js
'use strict'
const { register, unregister } = require('on-exit-leak-free')
const assert = require('assert')
function setup () {
// This object can be safely garbage collected,
// and the resulting shutdown function will not be called.
// There are no leaks.
const obj = { foo: 'bar' }
register(obj, shutdown)
// use registerBeforeExit(obj, shutdown) to execute the function only
// on beforeExit
// call unregister(obj) to remove
}
let shutdownCalled = false
// Please make sure that the function passed to register()
// does not create a closure around unnecessary objects.
function shutdown (obj, eventName) {
console.log(eventName) // beforeExit
shutdownCalled = true
assert.strictEqual(obj.foo, 'bar')
}
setup()
process.on('exit', function () {
assert.strictEqual(shutdownCalled, true)
})
```
## License
MIT

108
backend/node_modules/on-exit-leak-free/index.js generated vendored Normal file
View File

@@ -0,0 +1,108 @@
'use strict'
const refs = {
exit: [],
beforeExit: []
}
const functions = {
exit: onExit,
beforeExit: onBeforeExit
}
let registry
function ensureRegistry () {
if (registry === undefined) {
registry = new FinalizationRegistry(clear)
}
}
function install (event) {
if (refs[event].length > 0) {
return
}
process.on(event, functions[event])
}
function uninstall (event) {
if (refs[event].length > 0) {
return
}
process.removeListener(event, functions[event])
if (refs.exit.length === 0 && refs.beforeExit.length === 0) {
registry = undefined
}
}
function onExit () {
callRefs('exit')
}
function onBeforeExit () {
callRefs('beforeExit')
}
function callRefs (event) {
for (const ref of refs[event]) {
const obj = ref.deref()
const fn = ref.fn
// This should always happen, however GC is
// undeterministic so it might not happen.
/* istanbul ignore else */
if (obj !== undefined) {
fn(obj, event)
}
}
refs[event] = []
}
function clear (ref) {
for (const event of ['exit', 'beforeExit']) {
const index = refs[event].indexOf(ref)
refs[event].splice(index, index + 1)
uninstall(event)
}
}
function _register (event, obj, fn) {
if (obj === undefined) {
throw new Error('the object can\'t be undefined')
}
install(event)
const ref = new WeakRef(obj)
ref.fn = fn
ensureRegistry()
registry.register(obj, ref)
refs[event].push(ref)
}
function register (obj, fn) {
_register('exit', obj, fn)
}
function registerBeforeExit (obj, fn) {
_register('beforeExit', obj, fn)
}
function unregister (obj) {
if (registry === undefined) {
return
}
registry.unregister(obj)
for (const event of ['exit', 'beforeExit']) {
refs[event] = refs[event].filter((ref) => {
const _obj = ref.deref()
return _obj && _obj !== obj
})
uninstall(event)
}
}
module.exports = {
register,
registerBeforeExit,
unregister
}

37
backend/node_modules/on-exit-leak-free/package.json generated vendored Normal file
View File

@@ -0,0 +1,37 @@
{
"name": "on-exit-leak-free",
"version": "2.1.2",
"description": "Execute a function on exit without leaking memory, allowing all objects to be garbage collected",
"main": "index.js",
"scripts": {
"test": "standard | snazzy && tap test/*.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mcollina/on-exit-or-gc.git"
},
"keywords": [
"weak",
"reference",
"finalization",
"registry",
"process",
"exit",
"garbage",
"collector"
],
"author": "Matteo Collina <hello@matteocollina.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/mcollina/on-exit-or-gc/issues"
},
"homepage": "https://github.com/mcollina/on-exit-or-gc#readme",
"devDependencies": {
"snazzy": "^9.0.0",
"standard": "^17.0.0",
"tap": "^16.0.0"
},
"engines": {
"node": ">=14.0.0"
}
}

View File

@@ -0,0 +1,30 @@
'use strict'
const { test } = require('tap')
const { fork } = require('child_process')
const { join } = require('path')
const { once } = require('events')
const { register } = require('..')
const files = [
'close.js',
'beforeExit',
'gc-not-close.js',
'unregister.js'
]
for (const file of files) {
test(file, async ({ equal }) => {
const child = fork(join(__dirname, 'fixtures', file), [], {
execArgv: ['--expose-gc']
})
const [code] = await once(child, 'close')
equal(code, 0)
})
}
test('undefined', async ({ throws }) => {
throws(() => register(undefined))
})

View File

@@ -0,0 +1,23 @@
'use strict'
const t = require('tap')
const { register, unregister } = require('..')
process.on('warning', () => {
t.fail('warning emitted')
})
const objs = []
for (let i = 0; i < 20; i++) {
const obj = { i }
objs.push(obj)
register(obj, shutdown)
}
for (const obj of objs) {
unregister(obj)
}
t.pass('completed')
function shutdown () {}

View File

@@ -0,0 +1,33 @@
'use strict'
const { unregister, registerBeforeExit } = require('../..')
const assert = require('assert')
function setup () {
const obj = { foo: 'bar' }
registerBeforeExit(obj, shutdown)
}
let shutdownCalled = false
let timeoutFinished = false
function shutdown (obj, event) {
shutdownCalled = true
if (event === 'beforeExit') {
setTimeout(function () {
timeoutFinished = true
assert.strictEqual(obj.foo, 'bar')
unregister(obj)
}, 100)
process.on('beforeExit', function () {
assert.strictEqual(timeoutFinished, true)
})
} else {
throw new Error('different event')
}
}
setup()
process.on('exit', function () {
assert.strictEqual(shutdownCalled, true)
})

View File

@@ -0,0 +1,21 @@
'use strict'
const { register } = require('../..')
const assert = require('assert')
function setup () {
const obj = { foo: 'bar' }
register(obj, shutdown)
}
let shutdownCalled = false
function shutdown (obj) {
shutdownCalled = true
assert.strictEqual(obj.foo, 'bar')
}
setup()
process.on('exit', function () {
assert.strictEqual(shutdownCalled, true)
})

View File

@@ -0,0 +1,24 @@
'use strict'
const { register } = require('../..')
const assert = require('assert')
function setup () {
let obj = { foo: 'bar' }
register(obj, shutdown)
setImmediate(function () {
obj = undefined
gc() // eslint-disable-line
})
}
let shutdownCalled = false
function shutdown (obj) {
shutdownCalled = true
}
setup()
process.on('exit', function () {
assert.strictEqual(shutdownCalled, false)
})

View File

@@ -0,0 +1,24 @@
'use strict'
const { register, unregister } = require('../..')
const assert = require('assert')
function setup () {
const obj = { foo: 'bar' }
register(obj, shutdown)
setImmediate(function () {
unregister(obj)
unregister(obj) // twice, this should not throw
})
}
let shutdownCalled = false
function shutdown (obj) {
shutdownCalled = true
}
setup()
process.on('exit', function () {
assert.strictEqual(shutdownCalled, false)
})