@sequenceholdings/artifact-studio 0.2.5 → 0.3.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/README.md +35 -0
- package/VERSION-PIN.md +14 -3
- package/dist/api.d.ts +11 -1
- package/dist/api.js +26 -9
- package/dist/atlas-ui-css-plugin.d.ts +11 -7
- package/dist/atlas-ui-css-plugin.js +38 -10
- package/dist/build.d.ts +2 -2
- package/dist/build.js +14 -6
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +108 -37
- package/dist/dev-link.d.ts +1 -1
- package/dist/dev-link.js +2 -1
- package/dist/gateway/admission.d.ts +55 -0
- package/dist/gateway/admission.js +132 -0
- package/dist/gateway/control.d.ts +91 -0
- package/dist/gateway/control.js +113 -0
- package/dist/gateway/hosted-proxy.d.ts +36 -0
- package/dist/gateway/hosted-proxy.js +347 -0
- package/dist/gateway/release-admission.d.ts +23 -0
- package/dist/gateway/release-admission.js +259 -0
- package/dist/gateway/server.d.ts +29 -0
- package/dist/gateway/server.js +298 -0
- package/dist/gateway/session.d.ts +71 -0
- package/dist/gateway/session.js +143 -0
- package/dist/gateway/usage.d.ts +37 -0
- package/dist/gateway/usage.js +46 -0
- package/dist/gateway-main.d.ts +1 -0
- package/dist/gateway-main.js +84 -0
- package/dist/git-clone.d.ts +23 -1
- package/dist/git-clone.js +32 -15
- package/dist/manifest-next.d.ts +217 -0
- package/dist/manifest-next.js +120 -0
- package/dist/manifest-static.d.ts +76 -0
- package/dist/manifest-static.js +124 -0
- package/dist/manifest.d.ts +124 -19
- package/dist/manifest.js +12 -118
- package/dist/next/bridge.d.ts +47 -0
- package/dist/next/bridge.js +229 -0
- package/dist/next/browser-logs.d.ts +7 -0
- package/dist/next/browser-logs.js +51 -0
- package/dist/next/browser.d.ts +6 -0
- package/dist/next/browser.js +57 -0
- package/dist/next/protocol.d.ts +73 -0
- package/dist/next/protocol.js +56 -0
- package/dist/next/release.d.ts +15 -0
- package/dist/next/release.js +46 -0
- package/dist/next/requests.d.ts +15 -0
- package/dist/next/requests.js +59 -0
- package/dist/next/routes.d.ts +4 -0
- package/dist/next/routes.js +21 -0
- package/dist/next/streams.d.ts +16 -0
- package/dist/next/streams.js +132 -0
- package/dist/next/theme.d.ts +10 -0
- package/dist/next/theme.js +45 -0
- package/dist/next/transport.d.ts +15 -0
- package/dist/next/transport.js +13 -0
- package/dist/next-build.d.ts +29 -0
- package/dist/next-build.js +129 -0
- package/dist/next-cache/adapter-runtime.d.ts +51 -0
- package/dist/next-cache/adapter-runtime.js +73 -0
- package/dist/next-cache/component-handler.d.ts +3 -0
- package/dist/next-cache/component-handler.js +10 -0
- package/dist/next-cache/components.d.ts +20 -0
- package/dist/next-cache/components.js +113 -0
- package/dist/next-cache/config.d.ts +9 -0
- package/dist/next-cache/config.js +78 -0
- package/dist/next-cache/incremental-handler.d.ts +18 -0
- package/dist/next-cache/incremental-handler.js +17 -0
- package/dist/next-cache/incremental.d.ts +27 -0
- package/dist/next-cache/incremental.js +99 -0
- package/dist/next-cache/index.d.ts +18 -0
- package/dist/next-cache/index.js +16 -0
- package/dist/next-cache/memory-store.d.ts +27 -0
- package/dist/next-cache/memory-store.js +118 -0
- package/dist/next-cache/redis-scripts.d.ts +3 -0
- package/dist/next-cache/redis-scripts.js +85 -0
- package/dist/next-cache/redis-store.d.ts +18 -0
- package/dist/next-cache/redis-store.js +56 -0
- package/dist/next-cache/runtime.d.ts +29 -0
- package/dist/next-cache/runtime.js +63 -0
- package/dist/next-cache/serialization.d.ts +39 -0
- package/dist/next-cache/serialization.js +333 -0
- package/dist/next-cache/store.d.ts +54 -0
- package/dist/next-cache/store.js +45 -0
- package/dist/next-cache/valkey-transport.d.ts +52 -0
- package/dist/next-cache/valkey-transport.js +189 -0
- package/dist/next-dev-control.d.ts +48 -0
- package/dist/next-dev-control.js +63 -0
- package/dist/next-dev-process.d.ts +17 -0
- package/dist/next-dev-process.js +110 -0
- package/dist/next-dev.d.ts +12 -0
- package/dist/next-dev.js +267 -0
- package/dist/next-image-config.d.ts +9 -0
- package/dist/next-image-config.js +101 -0
- package/dist/next-project.d.ts +22 -0
- package/dist/next-project.js +64 -0
- package/dist/next-public-fonts-local.d.ts +7 -0
- package/dist/next-public-fonts-local.js +64 -0
- package/dist/next-public-fonts.d.ts +13 -0
- package/dist/next-public-fonts.js +49 -0
- package/dist/next-source-hash.d.ts +14 -0
- package/dist/next-source-hash.js +18 -0
- package/dist/next-source.d.ts +35 -0
- package/dist/next-source.js +155 -0
- package/dist/next.d.ts +9 -0
- package/dist/next.js +5 -0
- package/dist/project.d.ts +3 -0
- package/dist/project.js +9 -1
- package/dist/runtime-contracts.d.ts +229 -0
- package/dist/runtime-contracts.js +224 -0
- package/dist/sdk.d.ts +420 -1
- package/dist/sdk.js +35 -0
- package/dist/server/broker-contract.d.ts +68 -0
- package/dist/server/broker-contract.js +33 -0
- package/dist/server/client.d.ts +67 -0
- package/dist/server/client.js +159 -0
- package/dist/server/logger.d.ts +26 -0
- package/dist/server/logger.js +24 -0
- package/dist/server/release-forms.d.ts +13 -0
- package/dist/server/release-forms.js +124 -0
- package/dist/server/request-context.d.ts +74 -0
- package/dist/server/request-context.js +103 -0
- package/dist/server/runtime-config.d.ts +53 -0
- package/dist/server/runtime-config.js +64 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.js +4 -0
- package/dist/templates/nextjs/.artifactignore +14 -0
- package/dist/templates/nextjs/README.md +151 -0
- package/dist/templates/nextjs/app/about/page.tsx +26 -0
- package/dist/templates/nextjs/app/actions.ts +18 -0
- package/dist/templates/nextjs/app/api/health/route.ts +6 -0
- package/dist/templates/nextjs/app/components/counter.tsx +19 -0
- package/dist/templates/nextjs/app/components/greeting-form.tsx +38 -0
- package/dist/templates/nextjs/app/globals.css +4 -0
- package/dist/templates/nextjs/app/layout.tsx +27 -0
- package/dist/templates/nextjs/app/page.tsx +51 -0
- package/dist/templates/nextjs/app/providers.tsx +107 -0
- package/dist/templates/nextjs/artifact.bundle.yml +55 -0
- package/dist/templates/nextjs/next.config.mjs +27 -0
- package/dist/templates/nextjs/package.json +32 -0
- package/dist/templates/nextjs/pnpm-workspace.yaml +8 -0
- package/dist/templates/nextjs/postcss.config.mjs +5 -0
- package/dist/templates/nextjs/tsconfig.json +20 -0
- package/dist/templates/react-vite/artifact.bundle.yml +0 -1
- package/dist/templates/react-vite/package.json +1 -1
- package/dist/tunnel/broker.d.ts +75 -0
- package/dist/tunnel/broker.js +451 -0
- package/dist/tunnel/client.d.ts +22 -0
- package/dist/tunnel/client.js +177 -0
- package/dist/tunnel/index.d.ts +6 -0
- package/dist/tunnel/index.js +4 -0
- package/dist/tunnel/io.d.ts +33 -0
- package/dist/tunnel/io.js +108 -0
- package/dist/tunnel/peer.d.ts +25 -0
- package/dist/tunnel/peer.js +147 -0
- package/dist/tunnel/protocol.d.ts +69 -0
- package/dist/tunnel/protocol.js +196 -0
- package/dist/tunnel/redis-ownership.d.ts +38 -0
- package/dist/tunnel/redis-ownership.js +100 -0
- package/dist/tunnel/redis-socket.d.ts +13 -0
- package/dist/tunnel/redis-socket.js +48 -0
- package/dist/tunnel/redis-types.d.ts +70 -0
- package/dist/tunnel/redis-types.js +9 -0
- package/dist/tunnel/redis.d.ts +53 -0
- package/dist/tunnel/redis.js +391 -0
- package/dist/tunnel/transport.d.ts +17 -0
- package/dist/tunnel/transport.js +1 -0
- package/package.json +68 -4
- package/templates/nextjs/.artifactignore +14 -0
- package/templates/nextjs/README.md +151 -0
- package/templates/nextjs/app/about/page.tsx +26 -0
- package/templates/nextjs/app/actions.ts +18 -0
- package/templates/nextjs/app/api/health/route.ts +6 -0
- package/templates/nextjs/app/components/counter.tsx +19 -0
- package/templates/nextjs/app/components/greeting-form.tsx +38 -0
- package/templates/nextjs/app/globals.css +4 -0
- package/templates/nextjs/app/layout.tsx +27 -0
- package/templates/nextjs/app/page.tsx +51 -0
- package/templates/nextjs/app/providers.tsx +107 -0
- package/templates/nextjs/artifact.bundle.yml +55 -0
- package/templates/nextjs/next.config.mjs +27 -0
- package/templates/nextjs/package.json +32 -0
- package/templates/nextjs/pnpm-workspace.yaml +8 -0
- package/templates/nextjs/postcss.config.mjs +5 -0
- package/templates/nextjs/tsconfig.json +20 -0
- package/templates/react-vite/artifact.bundle.yml +0 -1
- package/templates/react-vite/package.json +1 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { Suspense, useEffect, useRef, useState, type ReactNode } from 'react'
|
|
4
|
+
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
|
5
|
+
import { PortalContainerProvider } from '@sequenceholdings/atlas-ui/next'
|
|
6
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
7
|
+
import {
|
|
8
|
+
createNextArtifactBridge,
|
|
9
|
+
createNextArtifactThemeApplier,
|
|
10
|
+
installNextArtifactBrowserIntegration,
|
|
11
|
+
type NextArtifactBridge,
|
|
12
|
+
type NextArtifactBridgeBootstrap,
|
|
13
|
+
type NextArtifactInitialContext,
|
|
14
|
+
} from '@sequenceholdings/artifact-studio/next'
|
|
15
|
+
|
|
16
|
+
type BrowserBootstrap = NextArtifactBridgeBootstrap & {
|
|
17
|
+
initialContext: NextArtifactInitialContext
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function Providers({ children, bootstrap }: {
|
|
21
|
+
children: ReactNode
|
|
22
|
+
bootstrap: BrowserBootstrap | null
|
|
23
|
+
}) {
|
|
24
|
+
const [queryClient] = useState(() => new QueryClient())
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<QueryClientProvider client={queryClient}>
|
|
28
|
+
<PortalContainerProvider>
|
|
29
|
+
<Suspense fallback={null}>
|
|
30
|
+
<AtlasConnection bootstrap={bootstrap} />
|
|
31
|
+
</Suspense>
|
|
32
|
+
{children}
|
|
33
|
+
</PortalContainerProvider>
|
|
34
|
+
</QueryClientProvider>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function AtlasConnection({ bootstrap }: { bootstrap: BrowserBootstrap | null }) {
|
|
39
|
+
const router = useRouter()
|
|
40
|
+
const pathname = usePathname()
|
|
41
|
+
const searchParams = useSearchParams()
|
|
42
|
+
const currentBridge = useRef<NextArtifactBridge | null>(null)
|
|
43
|
+
const [connectionError, setConnectionError] = useState(false)
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!bootstrap) return
|
|
47
|
+
let active = true
|
|
48
|
+
const theme = createNextArtifactThemeApplier({ root: document.documentElement })
|
|
49
|
+
const bridge = createNextArtifactBridge({
|
|
50
|
+
bootstrap,
|
|
51
|
+
initialContext: bootstrap.initialContext,
|
|
52
|
+
onNavigate: ({ path, replace }) => replace ? router.replace(path) : router.push(path),
|
|
53
|
+
})
|
|
54
|
+
currentBridge.current = bridge
|
|
55
|
+
const removeBrowserIntegration = installNextArtifactBrowserIntegration({ bridge })
|
|
56
|
+
const applyTheme = () => {
|
|
57
|
+
const snapshot = bridge.getSnapshot()
|
|
58
|
+
if (snapshot.theme) theme.apply({ theme: snapshot.theme })
|
|
59
|
+
}
|
|
60
|
+
const updateRoute = () => bridge.routeChanged({
|
|
61
|
+
path: `${window.location.pathname}${window.location.search}${window.location.hash}`,
|
|
62
|
+
})
|
|
63
|
+
const updateTitle = () => {
|
|
64
|
+
if (bridge.getSnapshot().status === 'ready') {
|
|
65
|
+
bridge.setDocumentTitle({ label: document.title })
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
applyTheme()
|
|
69
|
+
const unsubscribe = bridge.subscribe(applyTheme)
|
|
70
|
+
const titleObserver = new MutationObserver(updateTitle)
|
|
71
|
+
titleObserver.observe(document.head, { childList: true, characterData: true, subtree: true })
|
|
72
|
+
window.addEventListener('hashchange', updateRoute)
|
|
73
|
+
updateRoute()
|
|
74
|
+
void bridge.connect().then(() => {
|
|
75
|
+
if (!active) return
|
|
76
|
+
setConnectionError(false)
|
|
77
|
+
updateTitle()
|
|
78
|
+
}).catch(() => {
|
|
79
|
+
if (active) setConnectionError(true)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return () => {
|
|
83
|
+
active = false
|
|
84
|
+
window.removeEventListener('hashchange', updateRoute)
|
|
85
|
+
titleObserver.disconnect()
|
|
86
|
+
unsubscribe()
|
|
87
|
+
removeBrowserIntegration()
|
|
88
|
+
bridge.dispose()
|
|
89
|
+
theme.dispose()
|
|
90
|
+
currentBridge.current = null
|
|
91
|
+
}
|
|
92
|
+
}, [bootstrap, router])
|
|
93
|
+
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
const query = searchParams.toString()
|
|
96
|
+
currentBridge.current?.routeChanged({
|
|
97
|
+
path: `${pathname}${query ? `?${query}` : ''}${window.location.hash}`,
|
|
98
|
+
})
|
|
99
|
+
}, [pathname, searchParams])
|
|
100
|
+
|
|
101
|
+
if (!connectionError) return null
|
|
102
|
+
return (
|
|
103
|
+
<p role="alert" className="border-b border-border bg-card px-roomy py-default text-sm text-destructive">
|
|
104
|
+
The Atlas connection was interrupted. Reopen this preview from Artifact Studio.
|
|
105
|
+
</p>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
bundle:
|
|
2
|
+
name: {{slug}}
|
|
3
|
+
schema_version: 2
|
|
4
|
+
|
|
5
|
+
artifact:
|
|
6
|
+
project_id: {{slug}}
|
|
7
|
+
title: "{{title}}"
|
|
8
|
+
description: "A full-stack Next.js application managed by Atlas"
|
|
9
|
+
type: nextjs
|
|
10
|
+
app_root: .
|
|
11
|
+
|
|
12
|
+
runtime:
|
|
13
|
+
sdk: sequence
|
|
14
|
+
react: 19
|
|
15
|
+
node: 24
|
|
16
|
+
next: '16.3'
|
|
17
|
+
|
|
18
|
+
# Browser permissions and server permissions are separate declarations.
|
|
19
|
+
capabilities:
|
|
20
|
+
data:
|
|
21
|
+
read: []
|
|
22
|
+
write: []
|
|
23
|
+
api:
|
|
24
|
+
read: []
|
|
25
|
+
write: []
|
|
26
|
+
functions:
|
|
27
|
+
invoke: []
|
|
28
|
+
|
|
29
|
+
server:
|
|
30
|
+
capabilities:
|
|
31
|
+
data:
|
|
32
|
+
read: []
|
|
33
|
+
write: []
|
|
34
|
+
api:
|
|
35
|
+
read: []
|
|
36
|
+
write: []
|
|
37
|
+
functions:
|
|
38
|
+
invoke: []
|
|
39
|
+
secrets: []
|
|
40
|
+
egress: []
|
|
41
|
+
resources:
|
|
42
|
+
cpu: 1
|
|
43
|
+
memory_mb: 1024
|
|
44
|
+
concurrency: 20
|
|
45
|
+
min_instances: 0
|
|
46
|
+
max_instances: 3
|
|
47
|
+
timeout_seconds: 60
|
|
48
|
+
|
|
49
|
+
build:
|
|
50
|
+
public_env: {}
|
|
51
|
+
|
|
52
|
+
# Add a registered Atlas environment with `seq-studio artifact link -e <env>`.
|
|
53
|
+
targets:
|
|
54
|
+
local:
|
|
55
|
+
url: http://localhost:5001
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { withArtifactNextConfig } from '@sequenceholdings/artifact-studio/next-cache/config'
|
|
2
|
+
|
|
3
|
+
const devOrigin = process.env.ARTIFACT_STUDIO_DEV_ORIGIN
|
|
4
|
+
|
|
5
|
+
function allowedDevOrigins() {
|
|
6
|
+
if (!devOrigin) return []
|
|
7
|
+
const url = new URL(devOrigin)
|
|
8
|
+
if (
|
|
9
|
+
!['http:', 'https:'].includes(url.protocol) ||
|
|
10
|
+
url.username || url.password || url.pathname !== '/' || url.search || url.hash ||
|
|
11
|
+
url.hostname.includes('*')
|
|
12
|
+
) {
|
|
13
|
+
throw new Error('ARTIFACT_STUDIO_DEV_ORIGIN must be an exact HTTP(S) origin.')
|
|
14
|
+
}
|
|
15
|
+
// Next matches hostnames; the Atlas gateway validates the complete origin.
|
|
16
|
+
return [url.hostname]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @type {import('next').NextConfig} */
|
|
20
|
+
const config = {
|
|
21
|
+
output: 'standalone',
|
|
22
|
+
poweredByHeader: false,
|
|
23
|
+
reactStrictMode: true,
|
|
24
|
+
allowedDevOrigins: allowedDevOrigins(),
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default withArtifactNextConfig(config)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{slug}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"packageManager": "pnpm@10.28.2",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=24 <25"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "next dev --webpack --hostname 127.0.0.1",
|
|
11
|
+
"build": "next build",
|
|
12
|
+
"start": "next start --hostname 127.0.0.1",
|
|
13
|
+
"type-check": "next typegen && tsc --noEmit"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@sequenceholdings/artifact-studio": "{{artifactStudioVersion}}",
|
|
17
|
+
"@sequenceholdings/atlas-ui": "3.4.0",
|
|
18
|
+
"@tanstack/react-query": "^4.36.1",
|
|
19
|
+
"next": "16.3.4",
|
|
20
|
+
"react": "19.2.6",
|
|
21
|
+
"react-dom": "19.2.6",
|
|
22
|
+
"server-only": "0.0.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@tailwindcss/postcss": "^4.2.2",
|
|
26
|
+
"@types/node": "^24.0.0",
|
|
27
|
+
"@types/react": "^19.2.10",
|
|
28
|
+
"@types/react-dom": "^19.2.3",
|
|
29
|
+
"tailwindcss": "^4.2.2",
|
|
30
|
+
"typescript": "^5.6.0"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }]
|
|
17
|
+
},
|
|
18
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
|
|
19
|
+
"exclude": ["node_modules"]
|
|
20
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {},
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@sequenceholdings/artifact-studio": "^0.
|
|
12
|
+
"@sequenceholdings/artifact-studio": "^0.3.0",
|
|
13
13
|
"@sequenceholdings/atlas-ui": "^3.1.1",
|
|
14
14
|
"@tailwindcss/postcss": "^4.2.2",
|
|
15
15
|
"@tailwindcss/vite": "^4.2.2",
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { Duplex } from 'node:stream';
|
|
3
|
+
import { type TunnelLimits } from './peer.js';
|
|
4
|
+
import type { TunnelRelay } from './transport.js';
|
|
5
|
+
export interface TunnelLease {
|
|
6
|
+
sessionId: string;
|
|
7
|
+
epoch: number;
|
|
8
|
+
ownerId: string;
|
|
9
|
+
projectId: string;
|
|
10
|
+
environment: string;
|
|
11
|
+
expiresAt: number;
|
|
12
|
+
publicOrigin: string;
|
|
13
|
+
}
|
|
14
|
+
export interface TunnelOwner {
|
|
15
|
+
nodeId: string;
|
|
16
|
+
epoch: number;
|
|
17
|
+
expiresAt: number;
|
|
18
|
+
}
|
|
19
|
+
/** Production adapters must atomically fence epochs across nodes. Ingress routes
|
|
20
|
+
* to lookup().nodeId; this module never silently forwards to an arbitrary node. */
|
|
21
|
+
export interface TunnelOwnershipStore {
|
|
22
|
+
claim(lease: TunnelLease, nodeId: string): Promise<boolean>;
|
|
23
|
+
lookup(sessionId: string): Promise<TunnelOwner | null>;
|
|
24
|
+
release(sessionId: string, epoch: number, nodeId: string): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export interface GatewayAuthorization {
|
|
27
|
+
ownerId: string;
|
|
28
|
+
publicOrigin: string;
|
|
29
|
+
/** Signed, audience-scoped context minted by Atlas, never a user bearer. */
|
|
30
|
+
requestContext?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface TunnelBrokerOptions {
|
|
33
|
+
nodeId: string;
|
|
34
|
+
routing: TunnelOwnershipStore;
|
|
35
|
+
authorizeTunnel(request: IncomingMessage): Promise<TunnelLease | null>;
|
|
36
|
+
authorizeRequest(request: IncomingMessage, sessionId: string): Promise<GatewayAuthorization | null>;
|
|
37
|
+
validateLease(lease: TunnelLease): Promise<boolean>;
|
|
38
|
+
relay?: TunnelRelay;
|
|
39
|
+
resolveLease?(sessionId: string): Promise<TunnelLease | null>;
|
|
40
|
+
onTunnelClosed?(lease: TunnelLease): void;
|
|
41
|
+
limits?: Partial<TunnelLimits>;
|
|
42
|
+
}
|
|
43
|
+
/** Transport only: all identity, cookie bootstrap and FGA checks belong to the
|
|
44
|
+
* mandatory Atlas callbacks. An unconfigured broker cannot accept connections. */
|
|
45
|
+
export declare class ArtifactTunnelBroker {
|
|
46
|
+
private readonly options;
|
|
47
|
+
private readonly connections;
|
|
48
|
+
private readonly limits;
|
|
49
|
+
private readonly tunnels;
|
|
50
|
+
private readonly pendingConnections;
|
|
51
|
+
private readonly ownerTimers;
|
|
52
|
+
private closing;
|
|
53
|
+
constructor(options: TunnelBrokerOptions);
|
|
54
|
+
handleTunnelUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer): Promise<void>;
|
|
55
|
+
handleHttp(request: IncomingMessage, response: ServerResponse, sessionId: string): Promise<void>;
|
|
56
|
+
handleWebSocketUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer, sessionId: string): Promise<void>;
|
|
57
|
+
private authorize;
|
|
58
|
+
private valid;
|
|
59
|
+
private remoteConnection;
|
|
60
|
+
private attach;
|
|
61
|
+
private receive;
|
|
62
|
+
private finish;
|
|
63
|
+
private abort;
|
|
64
|
+
/** Immediate revocation and graceful service shutdown hook. */
|
|
65
|
+
disconnect(sessionId: string): void;
|
|
66
|
+
close(): void;
|
|
67
|
+
}
|
|
68
|
+
/** For one-process local development/tests only. Production must provide a shared
|
|
69
|
+
* compare-and-swap store and route ingress to the claimed owner. */
|
|
70
|
+
export declare class SingleProcessTunnelOwnership implements TunnelOwnershipStore {
|
|
71
|
+
private readonly owners;
|
|
72
|
+
claim(lease: TunnelLease, nodeId: string): Promise<boolean>;
|
|
73
|
+
lookup(sessionId: string): Promise<TunnelOwner | null>;
|
|
74
|
+
release(sessionId: string, epoch: number, nodeId: string): Promise<void>;
|
|
75
|
+
}
|