@commonpub/layer 0.21.5 → 0.21.6
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.
|
@@ -34,7 +34,7 @@ const visible = computed(() => !hasConsented.value && hasNonEssentialCookies.val
|
|
|
34
34
|
z-index: var(--z-toast);
|
|
35
35
|
background: var(--surface);
|
|
36
36
|
border-top: var(--border-width-default) solid var(--border);
|
|
37
|
-
box-shadow: 0 -
|
|
37
|
+
box-shadow: 0 -2px 0 var(--border);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
.cpub-consent-inner {
|
|
@@ -79,14 +79,14 @@ useFocusTrap(dialogRef, () => open.value, close);
|
|
|
79
79
|
<style scoped>
|
|
80
80
|
.cpub-rfd-overlay {
|
|
81
81
|
position: fixed; inset: 0; z-index: 9999;
|
|
82
|
-
background: rgba(0, 0, 0, 0.5); display: flex;
|
|
82
|
+
background: var(--color-surface-overlay, rgba(0, 0, 0, 0.5)); display: flex;
|
|
83
83
|
align-items: center; justify-content: center;
|
|
84
84
|
padding: 16px;
|
|
85
85
|
}
|
|
86
86
|
.cpub-rfd-dialog {
|
|
87
87
|
background: var(--bg); border: var(--border-width-default) solid var(--border);
|
|
88
88
|
width: 100%; max-width: 420px; padding: 24px;
|
|
89
|
-
box-shadow:
|
|
89
|
+
box-shadow: var(--shadow-md);
|
|
90
90
|
}
|
|
91
91
|
.cpub-rfd-header {
|
|
92
92
|
display: flex; align-items: center; justify-content: space-between;
|
|
@@ -10,6 +10,9 @@ const emit = defineEmits<{
|
|
|
10
10
|
import: [md: string, mode: 'append' | 'replace'];
|
|
11
11
|
}>();
|
|
12
12
|
|
|
13
|
+
const dialogRef = ref<HTMLElement | null>(null);
|
|
14
|
+
useFocusTrap(dialogRef, () => props.show, () => emit('close'));
|
|
15
|
+
|
|
13
16
|
const activeTab = ref<'paste' | 'file'>('paste');
|
|
14
17
|
const markdownText = ref('');
|
|
15
18
|
const mode = ref<'append' | 'replace'>('append');
|
|
@@ -58,9 +61,9 @@ async function readFile(file: File): Promise<void> {
|
|
|
58
61
|
<template>
|
|
59
62
|
<Teleport to="body">
|
|
60
63
|
<div v-if="show" class="md-import-overlay" @click.self="emit('close')">
|
|
61
|
-
<div class="md-import-dialog">
|
|
64
|
+
<div ref="dialogRef" class="md-import-dialog" role="dialog" aria-modal="true" aria-labelledby="md-import-title">
|
|
62
65
|
<div class="md-import-header">
|
|
63
|
-
<h2><i class="fa-brands fa-markdown"></i> Import Markdown</h2>
|
|
66
|
+
<h2 id="md-import-title"><i class="fa-brands fa-markdown"></i> Import Markdown</h2>
|
|
64
67
|
<button class="md-import-close" @click="emit('close')"><i class="fa-solid fa-xmark"></i></button>
|
|
65
68
|
</div>
|
|
66
69
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commonpub/layer",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./nuxt.config.ts",
|
|
6
6
|
"files": [
|
|
@@ -50,16 +50,16 @@
|
|
|
50
50
|
"vue": "^3.4.0",
|
|
51
51
|
"vue-router": "^4.3.0",
|
|
52
52
|
"zod": "^4.3.6",
|
|
53
|
-
"@commonpub/auth": "0.6.0",
|
|
54
|
-
"@commonpub/editor": "0.7.9",
|
|
55
53
|
"@commonpub/docs": "0.6.3",
|
|
56
|
-
"@commonpub/
|
|
54
|
+
"@commonpub/config": "0.12.0",
|
|
57
55
|
"@commonpub/learning": "0.5.2",
|
|
56
|
+
"@commonpub/auth": "0.6.0",
|
|
58
57
|
"@commonpub/explainer": "0.7.12",
|
|
59
|
-
"@commonpub/ui": "0.8.5",
|
|
60
|
-
"@commonpub/server": "2.53.0",
|
|
61
58
|
"@commonpub/schema": "0.16.0",
|
|
62
|
-
"@commonpub/
|
|
59
|
+
"@commonpub/editor": "0.7.9",
|
|
60
|
+
"@commonpub/protocol": "0.9.10",
|
|
61
|
+
"@commonpub/server": "2.53.1",
|
|
62
|
+
"@commonpub/ui": "0.8.5"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@testing-library/jest-dom": "^6.9.1",
|
|
@@ -47,6 +47,23 @@ export default defineEventHandler(async (event) => {
|
|
|
47
47
|
}
|
|
48
48
|
userConnections.set(userId, current + 1);
|
|
49
49
|
|
|
50
|
+
// Decrement exactly once on disconnect. Registered at handler scope (not
|
|
51
|
+
// inside ReadableStream.start) because start() is invoked lazily when the
|
|
52
|
+
// runtime begins pulling the stream — if the client aborts before that,
|
|
53
|
+
// start() never runs and an in-start cleanup would never fire, leaking
|
|
54
|
+
// the slot permanently and eventually 429-locking the user for the
|
|
55
|
+
// process lifetime. cleanup() also calls release(); the guard makes it
|
|
56
|
+
// idempotent so there is no double-decrement.
|
|
57
|
+
let released = false;
|
|
58
|
+
const release = (): void => {
|
|
59
|
+
if (released) return;
|
|
60
|
+
released = true;
|
|
61
|
+
const next = (userConnections.get(userId) ?? 1) - 1;
|
|
62
|
+
if (next <= 0) userConnections.delete(userId);
|
|
63
|
+
else userConnections.set(userId, next);
|
|
64
|
+
};
|
|
65
|
+
event.node.req.on('close', release);
|
|
66
|
+
|
|
50
67
|
const encoder = new TextEncoder();
|
|
51
68
|
const stream = new ReadableStream({
|
|
52
69
|
async start(controller) {
|
|
@@ -65,9 +82,7 @@ export default defineEventHandler(async (event) => {
|
|
|
65
82
|
unsubscribe = null;
|
|
66
83
|
}
|
|
67
84
|
try { controller.close(); } catch { /* already closed */ }
|
|
68
|
-
|
|
69
|
-
if (next <= 0) userConnections.delete(userId);
|
|
70
|
-
else userConnections.set(userId, next);
|
|
85
|
+
release();
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
async function sendCounts(): Promise<void> {
|