Compare commits

19 Commits

Author SHA1 Message Date
b3db73c8c7 chore(deps): update dependency @vitest/eslint-plugin to v1.3.10
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
/ playwright (push) Successful in 2m8s
CI/CD Pipeline / build-and-deploy (push) Successful in 3m17s
2025-09-18 22:07:33 +08:00
严浩
70688a626b refactor(eslint.config.ts): 在ESLint配置中添加对worker-configuration.d.ts的忽略
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 3m44s
/ playwright (push) Successful in 4m38s
2025-09-18 15:20:52 +08:00
严浩
7255675c9b ci(.github/workflows/ci-cd.yaml): 添加条件判断以限制部署到Cloudflare
Some checks failed
CI/CD Pipeline / build-and-deploy (push) Has been cancelled
/ playwright (push) Has been cancelled
2025-09-18 15:19:47 +08:00
严浩
f92ef0f870 feat: 添加 UnoCSS 样式到主要组件
All checks were successful
CI/CD Pipeline / build-and-deploy (push) Successful in 3m34s
/ playwright (push) Successful in 3m51s
- AppLayout.vue: 添加渐变背景和响应式布局
- App.vue: 美化主页面,包含卡片布局和绿色主题按钮
- index.page.vue: 创建彩色渐变的英雄区块,包含动画效果和交互卡片

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-18 13:16:22 +08:00
严浩
c928aa72bc chore(ci-cd): 重构工作流,合并构建和部署步骤
All checks were successful
/ playwright (push) Successful in 2m57s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m3s
2025-09-18 12:57:00 +08:00
严浩
077e7b5c90 chore(deps): 更新依赖和配置
Some checks failed
CI/CD Pipeline / lint-build-and-typecheck (push) Successful in 2m0s
CI/CD Pipeline / deploy (push) Has been cancelled
/ playwright (push) Has been cancelled
2025-09-18 12:54:13 +08:00
df0109205f chore(deps): update dependency @types/node to v22.18.5
All checks were successful
renovate/stability-days Updates have met minimum release age requirement
CI/CD Pipeline / lint-build-and-typecheck (push) Successful in 2m43s
/ playwright (push) Successful in 3m15s
CI/CD Pipeline / deploy (push) Successful in 1m23s
2025-09-18 05:58:24 +08:00
266192ffff chore(deps): update dependency @types/node to v22.18.4 2025-09-17 12:15:35 +08:00
74b608a2da chore(deps): update dependency unplugin-icons to v22.3.0 2025-09-15 09:38:54 +08:00
0dddb07909 chore(deps): update dependency eslint-plugin-oxlint to ~1.15.0 2025-09-15 06:28:18 +08:00
7305a7a4c0 chore(deps): update dependency vite-plugin-vue-devtools to v8.0.2 2025-09-15 03:30:02 +08:00
6fcc87b4dd chore(deps): update dependency oxlint to ~1.15.0 2025-09-14 18:44:09 +08:00
e7d701dfc6 chore(deps): update dependency @types/node to v22.18.3 2025-09-14 09:01:29 +08:00
671cea101b chore(deps): update dependency @intlify/unplugin-vue-i18n to v11.0.1 2025-09-14 02:06:31 +08:00
严浩
eb600d0b6b chore(package): 更新依赖包版本 2025-09-11 16:18:05 +08:00
严浩
87e701042f ci: 优化 GitHub Actions 工作流并添加单元测试 2025-09-09 23:22:35 +08:00
严浩
306ed9a527 ci: 更新 Playwright 配置以使用预览服务器
- 将 baseURL 固定为 http://localhost:4173,不再根据环境变量区分 CI 和本地环境
- 修改启动命令为先构建再启动预览服务器
- 设置 reuseExistingServer 为 true,优化服务器重用逻辑

(cherry picked from commit df6ffb99c8)
2025-09-09 23:11:00 +08:00
严浩
56d8a3aa49 test(e2e): 添加 AppLayout 组件的测试用例 2025-09-09 22:50:57 +08:00
严浩
394294904d build(deps): 更新依赖并添加 .npmrc 配置 2025-09-09 22:48:04 +08:00
13 changed files with 9489 additions and 82 deletions

2
.env
View File

@@ -1,2 +1,4 @@
VITE_BASE=/
VITE_BUILD_SOURCE_MAP=true
VITE_BUILD_COMMIT=
VITE_BUILD_TIME=

View File

@@ -12,7 +12,7 @@ on:
workflow_dispatch:
jobs:
lint-build-and-typecheck:
build-and-deploy:
runs-on: ubuntu-latest
container: gitea/runner-images:ubuntu-latest-slim # https://github.com/cloudflare/wrangler-action/issues/329#issuecomment-3046747722
@@ -28,6 +28,9 @@ jobs:
env:
VITE_BUILD_COMMIT: ${{ github.sha }}
- name: 🧪 单元测试
run: pnpm run test:unit
- name: 📊 计算构建大小
run: |
echo "📊 构建大小统计:"
@@ -41,33 +44,8 @@ jobs:
- name: ✅ 类型检查
run: pnpm run type-check # 要先 build保证 components.d.ts 存在
deploy:
runs-on: ubuntu-latest
needs: lint-build-and-typecheck
if: github.ref == 'refs/heads/main'
# https://github.com/cloudflare/wrangler-action/issues/329#issuecomment-3046747722
container:
image: gitea/runner-images:ubuntu-latest-slim
steps:
- name: 🛠️ 设置Node环境
uses: yanhao98/composite-actions/setup-node-environment@25eb4dc0c134cc9df2b7c569aa54140a366b45a8
- name: 📦 构建项目
run: pnpm run build-only
env:
VITE_BUILD_COMMIT: ${{ github.sha }}
# - name: 🚀 上传版本到 Cloudflare
# uses: cloudflare/wrangler-action@v3
# id: upload
# with:
# apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
# accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
# command: versions upload --tag "${{ github.sha }}" --message "Deploy commit ${{ github.sha }} from ${{ github.ref_name }}"
- name: 🚀 部署到 Cloudflare
if: github.ref == 'refs/heads/main'
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}

9
.npmrc Normal file
View File

@@ -0,0 +1,9 @@
# registry=https://registry.npmmirror.com/
# https://pnpm.io/zh/npmrc#node-mirrorltreleasedir
use-node-version=24.7.0
node-mirror:release=https://npmmirror.com/mirrors/node/ # pnpm config set node-mirror:release=https://npmmirror.com/mirrors/node/
node-mirror:rc=https://npmmirror.com/mirrors/node-rc/
node-mirror:nightly=https://npmmirror.com/mirrors/node-nightly/
# shamefully-hoist=true

View File

@@ -55,6 +55,5 @@ test.describe('Vue App', () => {
await page.goto('/')
const appLayout = page.locator('.app-layout')
await expect(appLayout).toBeVisible()
await expect(appLayout).toContainText('AppLayout')
})
})

View File

@@ -17,7 +17,7 @@ export default defineConfigWithVueTs(
files: ['**/*.{ts,mts,tsx,vue}'],
},
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
globalIgnores(['worker-configuration.d.ts', '**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
pluginVue.configs['flat/essential'],
vueTsConfigs.recommended,

View File

@@ -1,4 +1,5 @@
{
"packageManager": "pnpm@10.15.1",
"name": "vue-ts-example-2025",
"version": "0.0.0",
"private": true,
@@ -32,6 +33,7 @@
"wrangler:deploy": "pnpm run build && wrangler deploy",
"wrangler:versions:upload": "pnpm run build && wrangler versions upload",
"cf-typegen": "wrangler types",
"postinstall": "wrangler types",
"_dep:dedupe": "pnpm dedupe",
"_dep:update": "pnpm dlx taze major --interactive",
"_sizecheck:Treemap": "pnpm dlx vite-bundle-visualizer -t treemap",
@@ -48,15 +50,13 @@
]
},
"pnpm": {
"overrides": {
"vite": "$vite"
}
"overrides": {}
},
"dependencies": {
"@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.8.1",
"@formkit/auto-animate": "^0.9.0",
"@pinia/colada": "^0.17.3",
"@pinia/colada": "^0.17.4",
"@primeuix/themes": "^1.2.3",
"@unhead/vue": "^2.0.14",
"@vueuse/core": "^13.9.0",
@@ -70,12 +70,13 @@
"vue-router": "^4.5.1"
},
"devDependencies": {
"@cloudflare/vite-plugin": "^1.12.3",
"@cloudflare/vite-plugin": "^1.13.2",
"@commitlint/types": "^19.8.1",
"@intlify/unplugin-vue-i18n": "^11.0.0",
"@playwright/test": "^1.55.0",
"@prettier/plugin-oxc": "^0.0.4",
"@primevue/auto-import-resolver": "^4.3.9",
"@primevue/metadata": "^4.3.9",
"@tsconfig/node22": "^22.0.2",
"@types/jsdom": "^21.1.7",
"@types/node": "^22.18.1",
@@ -88,7 +89,7 @@
"@vue/test-utils": "^2.4.6",
"@vue/tsconfig": "^0.8.1",
"eslint": "^9.35.0",
"eslint-plugin-oxlint": "~1.14.0",
"eslint-plugin-oxlint": "~1.15.0",
"eslint-plugin-playwright": "^2.2.2",
"eslint-plugin-vue": "~10.4.0",
"husky": "^9.1.7",
@@ -97,9 +98,8 @@
"lint-staged": "^16.1.6",
"npm-run-all2": "^8.0.4",
"nprogress": "^0.2.0",
"oxlint": "~1.14.0",
"oxlint": "~1.15.0",
"prettier": "3.6.2",
"rolldown": "1.0.0-beta.36",
"typescript": "~5.9.2",
"unocss": "^66.5.1",
"unocss-preset-animations": "^1.2.1",
@@ -108,7 +108,7 @@
"unplugin-vue-components": "^29.0.0",
"unplugin-vue-markdown": "^29.1.0",
"unplugin-vue-router": "^0.15.0",
"vite": "npm:rolldown-vite@^7.1.8",
"vite": "^7.1.5",
"vite-plugin-checker": "^0.10.3",
"vite-plugin-fake-server": "^2.2.0",
"vite-plugin-image-optimizer": "^2.0.2",
@@ -118,6 +118,6 @@
"vitest": "^3.2.4",
"vue-macros": "3.0.0-beta.23",
"vue-tsc": "^3.0.6",
"wrangler": "^4.34.0"
"wrangler": "^4.37.1"
}
}

View File

@@ -2,7 +2,7 @@ import { defineConfig, devices } from '@playwright/test'
import process from 'node:process'
// const runningInVSCode = process.env.TERM_PROGRAM === 'vscode'
const baseURL = process.env.CI ? 'http://localhost:4173' : 'http://localhost:4730'
const baseURL = 'http://localhost:4173'
/**
* Read environment variables from file.
@@ -106,8 +106,8 @@ export default defineConfig({
* Use the preview server on CI for more realistic testing.
* Playwright will re-use the local server if there is already a dev-server running.
*/
command: process.env.CI ? 'pnpm run preview' : 'pnpm run dev',
command: 'pnpm run build-only; pnpm run preview',
port: Number(new URL(baseURL).port),
reuseExistingServer: !process.env.CI,
reuseExistingServer: true /* !process.env.CI */,
},
})

9231
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -11,19 +11,37 @@ const getName = async () => {
</script>
<template>
<div>
<h1>You did it!</h1>
<p>
Visit <a href="https://vuejs.org/" target="_blank" rel="noopener">vuejs.org</a> to read the
documentation
</p>
<button class="green" @click="getName" aria-label="get name">
Name from API is: {{ name }}
</button>
<div class="app-container bg-slate-50 min-h-screen">
<div class="container mx-auto px-6 py-8">
<h1 class="text-4xl font-extrabold text-emerald-600 mb-6 text-center">You did it!</h1>
<div class="bg-white rounded-lg shadow-lg p-8 mb-8">
<p class="text-lg text-gray-700 mb-6 text-center">
Visit
<a
href="https://vuejs.org/"
target="_blank"
rel="noopener"
class="text-emerald-500 hover:text-emerald-700 underline font-semibold"
>
vuejs.org
</a>
to read the documentation
</p>
<div class="flex justify-center">
<button
class="bg-emerald-500 hover:bg-emerald-600 text-white font-bold py-3 px-6 rounded-lg transition-colors duration-200 shadow-md hover:shadow-lg"
@click="getName"
aria-label="get name"
>
Name from API is: {{ name }}
</button>
</div>
</div>
</div>
<DynamicDialog />
<ConfirmDialog />
<Toast />
<RouterView />
</div>
<DynamicDialog /> <ConfirmDialog /> <Toast />
<RouterView />
</template>
<style scoped></style>

View File

@@ -1,9 +1,10 @@
<script setup lang="ts"></script>
<template>
<div class="app-layout">
<div>AppLayout</div>
<router-view />
<div class="app-layout min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
<main class="max-w-7xl mx-auto px-4 py-8">
<router-view />
</main>
</div>
</template>

View File

@@ -1,7 +1,31 @@
<script setup lang="ts"></script>
<template>
<div></div>
<div
class="hero-section bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 rounded-xl p-8 shadow-2xl"
>
<div class="text-center">
<h2 class="text-3xl font-bold text-white mb-4 animate-bounce">🎉 This is the index page</h2>
<p class="text-white/90 text-lg mb-6">Welcome to your awesome Vue.js application!</p>
<div class="flex justify-center space-x-4">
<div
class="bg-white/20 backdrop-blur-sm rounded-lg p-4 hover:bg-white/30 transition-all duration-300"
>
<span class="text-white font-semibold">Feature 1</span>
</div>
<div
class="bg-white/20 backdrop-blur-sm rounded-lg p-4 hover:bg-white/30 transition-all duration-300"
>
<span class="text-white font-semibold">Feature 2</span>
</div>
<div
class="bg-white/20 backdrop-blur-sm rounded-lg p-4 hover:bg-white/30 transition-all duration-300"
>
<span class="text-white font-semibold">Feature 3</span>
</div>
</div>
</div>
</div>
</template>
<style scoped></style>

View File

@@ -1,18 +1,19 @@
import { fileURLToPath, URL } from 'node:url'
import { createViteProxy } from 'utils4u/vite'
import { defineConfig, type DepOptimizationOptions } from 'vite'
import { defineConfig, loadEnv, type DepOptimizationOptions } from 'vite'
import { Plugins } from './vite.config.plugins'
// import { createRolldownSplitChunks } from './vite.config.rolldown.split-chunks'
// https://vite.dev/config/
export default defineConfig(({ command /* mode */ }) => {
export default defineConfig(({ command, mode }) => {
const isBuild = command === 'build'
// const env = loadEnv(mode, process.cwd())
const env = loadEnv(mode, process.cwd())
return {
// build: createRolldownSplitChunks(),
// base: env.VITE_BASE,
base: env.VITE_BASE,
build: {
sourcemap: env.VITE_BUILD_SOURCE_MAP === 'true',
},
plugins: Plugins(),
resolve: {
alias: {
@@ -30,14 +31,14 @@ export default defineConfig(({ command /* mode */ }) => {
}
})
// const primevuecomponents = await (async () => {
// const { components } = await import('@primevue/metadata')
// return components.map((c) => c.from).filter((c) => c !== undefined)
// })()
const primevuecomponents = await (async () => {
const { components } = await import('@primevue/metadata')
return components.map((c) => c.from).filter((c) => c !== undefined)
})()
function optimizeDeps(): DepOptimizationOptions {
return {
include: [
// ...primevuecomponents,
...primevuecomponents,
'@primeuix/themes',
'@primeuix/themes/lara',
'class-variance-authority',

View File

@@ -1,6 +1,6 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types` (hash: a5d3a0d06638640f4072385a766cb44d)
// Runtime types generated with workerd@1.20250902.0 2025-09-09
// Runtime types generated with workerd@1.20250906.0 2025-09-09
declare namespace Cloudflare {
interface Env {
KV: KVNamespace;
@@ -414,7 +414,7 @@ interface DurableObjectId {
equals(other: DurableObjectId): boolean;
readonly name?: string;
}
interface DurableObjectNamespace<T extends Rpc.DurableObjectBranded | undefined = undefined> {
declare abstract class DurableObjectNamespace<T extends Rpc.DurableObjectBranded | undefined = undefined> {
newUniqueId(options?: DurableObjectNamespaceNewUniqueIdOptions): DurableObjectId;
idFromName(name: string): DurableObjectId;
idFromString(id: string): DurableObjectId;
@@ -432,6 +432,7 @@ interface DurableObjectNamespaceGetDurableObjectOptions {
}
interface DurableObjectState {
waitUntil(promise: Promise<any>): void;
props: any;
readonly id: DurableObjectId;
readonly storage: DurableObjectStorage;
container?: Container;
@@ -474,6 +475,7 @@ interface DurableObjectStorage {
deleteAlarm(options?: DurableObjectSetAlarmOptions): Promise<void>;
sync(): Promise<void>;
sql: SqlStorage;
kv: SyncKvStorage;
transactionSync<T>(closure: () => T): T;
getCurrentBookmark(): Promise<string>;
getBookmarkForTime(timestamp: number | Date): Promise<string>;
@@ -2045,6 +2047,7 @@ interface TraceItem {
readonly scriptVersion?: ScriptVersion;
readonly dispatchNamespace?: string;
readonly scriptTags?: string[];
readonly durableObjectId?: string;
readonly outcome: string;
readonly executionModel: string;
readonly truncated: boolean;
@@ -2566,6 +2569,23 @@ declare class MessageChannel {
interface MessagePortPostMessageOptions {
transfer?: any[];
}
interface SyncKvStorage {
get<T = unknown>(key: string): T | undefined;
list<T = unknown>(options?: SyncKvListOptions): Iterable<[
string,
T
]>;
put<T>(key: string, value: T): void;
delete(key: string): boolean;
}
interface SyncKvListOptions {
start?: string;
startAfter?: string;
end?: string;
prefix?: string;
reverse?: boolean;
limit?: number;
}
type AiImageClassificationInput = {
image: number[];
};
@@ -5440,7 +5460,7 @@ type AIGatewayHeaders = {
[key: string]: string | number | boolean | object;
};
type AIGatewayUniversalRequest = {
provider: AIGatewayProviders | string;
provider: AIGatewayProviders | string; // eslint-disable-line
endpoint: string;
headers: Partial<AIGatewayHeaders>;
query: unknown;
@@ -5456,7 +5476,7 @@ declare abstract class AiGateway {
gateway?: UniversalGatewayOptions;
extraHeaders?: object;
}): Promise<Response>;
getUrl(provider?: AIGatewayProviders | string): Promise<string>;
getUrl(provider?: AIGatewayProviders | string): Promise<string>; // eslint-disable-line
}
interface AutoRAGInternalError extends Error {
}
@@ -6555,6 +6575,7 @@ type ImageOutputOptions = {
format: 'image/jpeg' | 'image/png' | 'image/gif' | 'image/webp' | 'image/avif' | 'rgb' | 'rgba';
quality?: number;
background?: string;
anim?: boolean;
};
interface ImagesBinding {
/**
@@ -6613,6 +6634,108 @@ interface ImagesError extends Error {
readonly message: string;
readonly stack?: string;
}
/**
* Media binding for transforming media streams.
* Provides the entry point for media transformation operations.
*/
interface MediaBinding {
/**
* Creates a media transformer from an input stream.
* @param media - The input media bytes
* @returns A MediaTransformer instance for applying transformations
*/
input(media: ReadableStream<Uint8Array>): MediaTransformer;
}
/**
* Media transformer for applying transformation operations to media content.
* Handles sizing, fitting, and other input transformation parameters.
*/
interface MediaTransformer {
/**
* Applies transformation options to the media content.
* @param transform - Configuration for how the media should be transformed
* @returns A generator for producing the transformed media output
*/
transform(transform: MediaTransformationInputOptions): MediaTransformationGenerator;
}
/**
* Generator for producing media transformation results.
* Configures the output format and parameters for the transformed media.
*/
interface MediaTransformationGenerator {
/**
* Generates the final media output with specified options.
* @param output - Configuration for the output format and parameters
* @returns The final transformation result containing the transformed media
*/
output(output: MediaTransformationOutputOptions): MediaTransformationResult;
}
/**
* Result of a media transformation operation.
* Provides multiple ways to access the transformed media content.
*/
interface MediaTransformationResult {
/**
* Returns the transformed media as a readable stream of bytes.
* @returns A stream containing the transformed media data
*/
media(): ReadableStream<Uint8Array>;
/**
* Returns the transformed media as an HTTP response object.
* @returns The transformed media as a Response, ready to store in cache or return to users
*/
response(): Response;
/**
* Returns the MIME type of the transformed media.
* @returns The content type string (e.g., 'image/jpeg', 'video/mp4')
*/
contentType(): string;
}
/**
* Configuration options for transforming media input.
* Controls how the media should be resized and fitted.
*/
type MediaTransformationInputOptions = {
/** How the media should be resized to fit the specified dimensions */
fit?: 'contain' | 'cover' | 'scale-down';
/** Target width in pixels */
width?: number;
/** Target height in pixels */
height?: number;
};
/**
* Configuration options for Media Transformations output.
* Controls the format, timing, and type of the generated output.
*/
type MediaTransformationOutputOptions = {
/**
* Output mode determining the type of media to generate
*/
mode?: 'video' | 'spritesheet' | 'frame' | 'audio';
/** Whether to include audio in the output */
audio?: boolean;
/**
* Starting timestamp for frame extraction or start time for clips. (e.g. '2s').
*/
time?: string;
/**
* Duration for video clips, audio extraction, and spritesheet generation (e.g. '5s').
*/
duration?: string;
/**
* Output format for the generated media.
*/
format?: 'jpg' | 'png' | 'm4a';
};
/**
* Error object for media transformation operations.
* Extends the standard Error interface with additional media-specific information.
*/
interface MediaError extends Error {
readonly code: number;
readonly message: string;
readonly stack?: string;
}
type Params<P extends string = any> = Record<P, string | string[]>;
type EventContext<Env, P extends string, Data> = {
request: Request<unknown, IncomingRequestCfProperties<unknown>>;
@@ -6999,21 +7122,17 @@ declare namespace TailStream {
readonly tag?: string;
readonly message?: string;
}
interface Trigger {
readonly traceId: string;
readonly invocationId: string;
readonly spanId: string;
}
interface Onset {
readonly type: "onset";
readonly attributes: Attribute[];
// id for the span being opened by this Onset event.
readonly spanId: string;
readonly dispatchNamespace?: string;
readonly entrypoint?: string;
readonly executionModel: string;
readonly scriptName?: string;
readonly scriptTags?: string[];
readonly scriptVersion?: ScriptVersion;
readonly trigger?: Trigger;
readonly info: FetchEventInfo | JsRpcEventInfo | ScheduledEventInfo | AlarmEventInfo | QueueEventInfo | EmailEventInfo | TraceEventInfo | HibernatableWebSocketEventInfo | CustomEventInfo;
}
interface Outcome {
@@ -7025,6 +7144,8 @@ declare namespace TailStream {
interface SpanOpen {
readonly type: "spanOpen";
readonly name: string;
// id for the span being opened by this SpanOpen event.
readonly spanId: string;
readonly info?: FetchEventInfo | JsRpcEventInfo | Attributes;
}
interface SpanClose {
@@ -7047,6 +7168,10 @@ declare namespace TailStream {
readonly level: "debug" | "error" | "info" | "log" | "warn";
readonly message: object;
}
// This marks the worker handler return information.
// This is separate from Outcome because the worker invocation can live for a long time after
// returning. For example - Websockets that return an http upgrade response but then continue
// streaming information or SSE http connections.
interface Return {
readonly type: "return";
readonly info?: FetchResponseInfo;
@@ -7060,9 +7185,28 @@ declare namespace TailStream {
readonly info: Attribute[];
}
type EventType = Onset | Outcome | SpanOpen | SpanClose | DiagnosticChannelEvent | Exception | Log | Return | Attributes;
// Context in which this trace event lives.
interface SpanContext {
// Single id for the entire top-level invocation
// This should be a new traceId for the first worker stage invoked in the eyeball request and then
// same-account service-bindings should reuse the same traceId but cross-account service-bindings
// should use a new traceId.
readonly traceId: string;
// spanId in which this event is handled
// for Onset and SpanOpen events this would be the parent span id
// for Outcome and SpanClose these this would be the span id of the opening Onset and SpanOpen events
// For Hibernate and Mark this would be the span under which they were emitted.
// spanId is not set ONLY if:
// 1. This is an Onset event
// 2. We are not inherting any SpanContext. (e.g. this is a cross-account service binding or a new top-level invocation)
readonly spanId?: string;
}
interface TailEvent<Event extends EventType> {
// invocation id of the currently invoked worker stage.
// invocation id will always be unique to every Onset event and will be the same until the Outcome event.
readonly invocationId: string;
readonly spanId: string;
// Inherited spanContext for this event.
readonly spanContext: SpanContext;
readonly timestamp: Date;
readonly sequence: number;
readonly event: Event;