@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.
Files changed (187) hide show
  1. package/README.md +35 -0
  2. package/VERSION-PIN.md +14 -3
  3. package/dist/api.d.ts +11 -1
  4. package/dist/api.js +26 -9
  5. package/dist/atlas-ui-css-plugin.d.ts +11 -7
  6. package/dist/atlas-ui-css-plugin.js +38 -10
  7. package/dist/build.d.ts +2 -2
  8. package/dist/build.js +14 -6
  9. package/dist/cli.d.ts +1 -1
  10. package/dist/cli.js +108 -37
  11. package/dist/dev-link.d.ts +1 -1
  12. package/dist/dev-link.js +2 -1
  13. package/dist/gateway/admission.d.ts +55 -0
  14. package/dist/gateway/admission.js +132 -0
  15. package/dist/gateway/control.d.ts +91 -0
  16. package/dist/gateway/control.js +113 -0
  17. package/dist/gateway/hosted-proxy.d.ts +36 -0
  18. package/dist/gateway/hosted-proxy.js +347 -0
  19. package/dist/gateway/release-admission.d.ts +23 -0
  20. package/dist/gateway/release-admission.js +259 -0
  21. package/dist/gateway/server.d.ts +29 -0
  22. package/dist/gateway/server.js +298 -0
  23. package/dist/gateway/session.d.ts +71 -0
  24. package/dist/gateway/session.js +143 -0
  25. package/dist/gateway/usage.d.ts +37 -0
  26. package/dist/gateway/usage.js +46 -0
  27. package/dist/gateway-main.d.ts +1 -0
  28. package/dist/gateway-main.js +84 -0
  29. package/dist/git-clone.d.ts +23 -1
  30. package/dist/git-clone.js +32 -15
  31. package/dist/manifest-next.d.ts +217 -0
  32. package/dist/manifest-next.js +120 -0
  33. package/dist/manifest-static.d.ts +76 -0
  34. package/dist/manifest-static.js +124 -0
  35. package/dist/manifest.d.ts +124 -19
  36. package/dist/manifest.js +12 -118
  37. package/dist/next/bridge.d.ts +47 -0
  38. package/dist/next/bridge.js +229 -0
  39. package/dist/next/browser-logs.d.ts +7 -0
  40. package/dist/next/browser-logs.js +51 -0
  41. package/dist/next/browser.d.ts +6 -0
  42. package/dist/next/browser.js +57 -0
  43. package/dist/next/protocol.d.ts +73 -0
  44. package/dist/next/protocol.js +56 -0
  45. package/dist/next/release.d.ts +15 -0
  46. package/dist/next/release.js +46 -0
  47. package/dist/next/requests.d.ts +15 -0
  48. package/dist/next/requests.js +59 -0
  49. package/dist/next/routes.d.ts +4 -0
  50. package/dist/next/routes.js +21 -0
  51. package/dist/next/streams.d.ts +16 -0
  52. package/dist/next/streams.js +132 -0
  53. package/dist/next/theme.d.ts +10 -0
  54. package/dist/next/theme.js +45 -0
  55. package/dist/next/transport.d.ts +15 -0
  56. package/dist/next/transport.js +13 -0
  57. package/dist/next-build.d.ts +29 -0
  58. package/dist/next-build.js +129 -0
  59. package/dist/next-cache/adapter-runtime.d.ts +51 -0
  60. package/dist/next-cache/adapter-runtime.js +73 -0
  61. package/dist/next-cache/component-handler.d.ts +3 -0
  62. package/dist/next-cache/component-handler.js +10 -0
  63. package/dist/next-cache/components.d.ts +20 -0
  64. package/dist/next-cache/components.js +113 -0
  65. package/dist/next-cache/config.d.ts +9 -0
  66. package/dist/next-cache/config.js +78 -0
  67. package/dist/next-cache/incremental-handler.d.ts +18 -0
  68. package/dist/next-cache/incremental-handler.js +17 -0
  69. package/dist/next-cache/incremental.d.ts +27 -0
  70. package/dist/next-cache/incremental.js +99 -0
  71. package/dist/next-cache/index.d.ts +18 -0
  72. package/dist/next-cache/index.js +16 -0
  73. package/dist/next-cache/memory-store.d.ts +27 -0
  74. package/dist/next-cache/memory-store.js +118 -0
  75. package/dist/next-cache/redis-scripts.d.ts +3 -0
  76. package/dist/next-cache/redis-scripts.js +85 -0
  77. package/dist/next-cache/redis-store.d.ts +18 -0
  78. package/dist/next-cache/redis-store.js +56 -0
  79. package/dist/next-cache/runtime.d.ts +29 -0
  80. package/dist/next-cache/runtime.js +63 -0
  81. package/dist/next-cache/serialization.d.ts +39 -0
  82. package/dist/next-cache/serialization.js +333 -0
  83. package/dist/next-cache/store.d.ts +54 -0
  84. package/dist/next-cache/store.js +45 -0
  85. package/dist/next-cache/valkey-transport.d.ts +52 -0
  86. package/dist/next-cache/valkey-transport.js +189 -0
  87. package/dist/next-dev-control.d.ts +48 -0
  88. package/dist/next-dev-control.js +63 -0
  89. package/dist/next-dev-process.d.ts +17 -0
  90. package/dist/next-dev-process.js +110 -0
  91. package/dist/next-dev.d.ts +12 -0
  92. package/dist/next-dev.js +267 -0
  93. package/dist/next-image-config.d.ts +9 -0
  94. package/dist/next-image-config.js +101 -0
  95. package/dist/next-project.d.ts +22 -0
  96. package/dist/next-project.js +64 -0
  97. package/dist/next-public-fonts-local.d.ts +7 -0
  98. package/dist/next-public-fonts-local.js +64 -0
  99. package/dist/next-public-fonts.d.ts +13 -0
  100. package/dist/next-public-fonts.js +49 -0
  101. package/dist/next-source-hash.d.ts +14 -0
  102. package/dist/next-source-hash.js +18 -0
  103. package/dist/next-source.d.ts +35 -0
  104. package/dist/next-source.js +155 -0
  105. package/dist/next.d.ts +9 -0
  106. package/dist/next.js +5 -0
  107. package/dist/project.d.ts +3 -0
  108. package/dist/project.js +9 -1
  109. package/dist/runtime-contracts.d.ts +229 -0
  110. package/dist/runtime-contracts.js +224 -0
  111. package/dist/sdk.d.ts +420 -1
  112. package/dist/sdk.js +35 -0
  113. package/dist/server/broker-contract.d.ts +68 -0
  114. package/dist/server/broker-contract.js +33 -0
  115. package/dist/server/client.d.ts +67 -0
  116. package/dist/server/client.js +159 -0
  117. package/dist/server/logger.d.ts +26 -0
  118. package/dist/server/logger.js +24 -0
  119. package/dist/server/release-forms.d.ts +13 -0
  120. package/dist/server/release-forms.js +124 -0
  121. package/dist/server/request-context.d.ts +74 -0
  122. package/dist/server/request-context.js +103 -0
  123. package/dist/server/runtime-config.d.ts +53 -0
  124. package/dist/server/runtime-config.js +64 -0
  125. package/dist/server.d.ts +8 -0
  126. package/dist/server.js +4 -0
  127. package/dist/templates/nextjs/.artifactignore +14 -0
  128. package/dist/templates/nextjs/README.md +151 -0
  129. package/dist/templates/nextjs/app/about/page.tsx +26 -0
  130. package/dist/templates/nextjs/app/actions.ts +18 -0
  131. package/dist/templates/nextjs/app/api/health/route.ts +6 -0
  132. package/dist/templates/nextjs/app/components/counter.tsx +19 -0
  133. package/dist/templates/nextjs/app/components/greeting-form.tsx +38 -0
  134. package/dist/templates/nextjs/app/globals.css +4 -0
  135. package/dist/templates/nextjs/app/layout.tsx +27 -0
  136. package/dist/templates/nextjs/app/page.tsx +51 -0
  137. package/dist/templates/nextjs/app/providers.tsx +107 -0
  138. package/dist/templates/nextjs/artifact.bundle.yml +55 -0
  139. package/dist/templates/nextjs/next.config.mjs +27 -0
  140. package/dist/templates/nextjs/package.json +32 -0
  141. package/dist/templates/nextjs/pnpm-workspace.yaml +8 -0
  142. package/dist/templates/nextjs/postcss.config.mjs +5 -0
  143. package/dist/templates/nextjs/tsconfig.json +20 -0
  144. package/dist/templates/react-vite/artifact.bundle.yml +0 -1
  145. package/dist/templates/react-vite/package.json +1 -1
  146. package/dist/tunnel/broker.d.ts +75 -0
  147. package/dist/tunnel/broker.js +451 -0
  148. package/dist/tunnel/client.d.ts +22 -0
  149. package/dist/tunnel/client.js +177 -0
  150. package/dist/tunnel/index.d.ts +6 -0
  151. package/dist/tunnel/index.js +4 -0
  152. package/dist/tunnel/io.d.ts +33 -0
  153. package/dist/tunnel/io.js +108 -0
  154. package/dist/tunnel/peer.d.ts +25 -0
  155. package/dist/tunnel/peer.js +147 -0
  156. package/dist/tunnel/protocol.d.ts +69 -0
  157. package/dist/tunnel/protocol.js +196 -0
  158. package/dist/tunnel/redis-ownership.d.ts +38 -0
  159. package/dist/tunnel/redis-ownership.js +100 -0
  160. package/dist/tunnel/redis-socket.d.ts +13 -0
  161. package/dist/tunnel/redis-socket.js +48 -0
  162. package/dist/tunnel/redis-types.d.ts +70 -0
  163. package/dist/tunnel/redis-types.js +9 -0
  164. package/dist/tunnel/redis.d.ts +53 -0
  165. package/dist/tunnel/redis.js +391 -0
  166. package/dist/tunnel/transport.d.ts +17 -0
  167. package/dist/tunnel/transport.js +1 -0
  168. package/package.json +68 -4
  169. package/templates/nextjs/.artifactignore +14 -0
  170. package/templates/nextjs/README.md +151 -0
  171. package/templates/nextjs/app/about/page.tsx +26 -0
  172. package/templates/nextjs/app/actions.ts +18 -0
  173. package/templates/nextjs/app/api/health/route.ts +6 -0
  174. package/templates/nextjs/app/components/counter.tsx +19 -0
  175. package/templates/nextjs/app/components/greeting-form.tsx +38 -0
  176. package/templates/nextjs/app/globals.css +4 -0
  177. package/templates/nextjs/app/layout.tsx +27 -0
  178. package/templates/nextjs/app/page.tsx +51 -0
  179. package/templates/nextjs/app/providers.tsx +107 -0
  180. package/templates/nextjs/artifact.bundle.yml +55 -0
  181. package/templates/nextjs/next.config.mjs +27 -0
  182. package/templates/nextjs/package.json +32 -0
  183. package/templates/nextjs/pnpm-workspace.yaml +8 -0
  184. package/templates/nextjs/postcss.config.mjs +5 -0
  185. package/templates/nextjs/tsconfig.json +20 -0
  186. package/templates/react-vite/artifact.bundle.yml +0 -1
  187. 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,8 @@
1
+ packages:
2
+ - '.'
3
+
4
+ minimumReleaseAge: 10080
5
+ strictDepBuilds: true
6
+ allowBuilds:
7
+ '@tailwindcss/oxide': false
8
+ sharp: false
@@ -0,0 +1,5 @@
1
+ export default {
2
+ plugins: {
3
+ '@tailwindcss/postcss': {},
4
+ },
5
+ }
@@ -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
+ }
@@ -29,4 +29,3 @@ capabilities:
29
29
  targets:
30
30
  local:
31
31
  url: http://localhost:5001
32
- visibility: private
@@ -9,7 +9,7 @@
9
9
  },
10
10
  "dependencies": {},
11
11
  "devDependencies": {
12
- "@sequenceholdings/artifact-studio": "^0.2.4",
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
+ }