State a version once

A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.

Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.
This commit is contained in:
2026-08-29 13:46:58 -07:00
parent c24fe51f44
commit 12b414f972
8 changed files with 414 additions and 210 deletions
+175 -175
View File
@@ -36,120 +36,120 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@ant-design/colors": "6.0.0", "@ant-design/colors": "catalog:",
"@ant-design/v5-patch-for-react-19": "1.0.3", "@ant-design/v5-patch-for-react-19": "catalog:",
"@codemirror/autocomplete": "6.18.6", "@codemirror/autocomplete": "catalog:",
"@codemirror/lang-javascript": "6.2.3", "@codemirror/lang-javascript": "catalog:",
"@codemirror/state": "6.5.2", "@codemirror/state": "catalog:",
"@codemirror/view": "6.36.6", "@codemirror/view": "catalog:",
"@dnd-kit/core": "6.1.0", "@dnd-kit/core": "catalog:",
"@dnd-kit/modifiers": "7.0.0", "@dnd-kit/modifiers": "catalog:",
"@dnd-kit/sortable": "8.0.0", "@dnd-kit/sortable": "catalog:",
"@dnd-kit/utilities": "3.2.2", "@dnd-kit/utilities": "catalog:",
"@grafana/data": "^11.6.14", "@grafana/data": "catalog:",
"@hanzo/font": "^1.8.0", "@hanzo/font": "catalog:",
"@hanzo/gui": "^8.0.1", "@hanzo/gui": "catalog:",
"@hanzo/insights": "^1.358.1", "@hanzo/insights": "catalog:",
"@hanzo/ui": "^8.0.39", "@hanzo/ui": "catalog:",
"@monaco-editor/react": "^4.7.0", "@monaco-editor/react": "catalog:",
"@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-dialog": "catalog:",
"@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-dropdown-menu": "catalog:",
"@radix-ui/react-popover": "1.1.15", "@radix-ui/react-popover": "catalog:",
"@radix-ui/react-select": "2.2.6", "@radix-ui/react-select": "catalog:",
"@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-tooltip": "catalog:",
"@sentry/react": "8.41.0", "@sentry/react": "catalog:",
"@sentry/vite-plugin": "2.22.6", "@sentry/vite-plugin": "catalog:",
"@tanstack/react-table": "8.20.6", "@tanstack/react-table": "catalog:",
"@tanstack/react-virtual": "3.11.2", "@tanstack/react-virtual": "catalog:",
"@uiw/codemirror-theme-copilot": "4.23.11", "@uiw/codemirror-theme-copilot": "catalog:",
"@uiw/codemirror-theme-github": "4.24.1", "@uiw/codemirror-theme-github": "catalog:",
"@uiw/react-codemirror": "4.23.10", "@uiw/react-codemirror": "catalog:",
"@visx/group": "4.0.0", "@visx/group": "catalog:",
"@visx/hierarchy": "4.0.0", "@visx/hierarchy": "catalog:",
"@visx/shape": "4.0.0", "@visx/shape": "catalog:",
"@visx/tooltip": "4.0.0", "@visx/tooltip": "catalog:",
"@visx/vendor": "4.0.0", "@visx/vendor": "catalog:",
"@vitejs/plugin-react": "5.1.4", "@vitejs/plugin-react": "catalog:",
"ansi-to-html": "0.7.2", "ansi-to-html": "catalog:",
"antd": "5.29.3", "antd": "catalog:",
"antd-table-saveas-excel": "2.2.1", "antd-table-saveas-excel": "catalog:",
"antlr4": "4.13.2", "antlr4": "catalog:",
"axios": "1.16.0", "axios": "catalog:",
"babel-jest": "^29.6.4", "babel-jest": "catalog:",
"chart.js": "3.9.1", "chart.js": "catalog:",
"chartjs-adapter-date-fns": "^2.0.0", "chartjs-adapter-date-fns": "catalog:",
"chartjs-plugin-annotation": "^1.4.0", "chartjs-plugin-annotation": "catalog:",
"classnames": "2.3.2", "classnames": "catalog:",
"clsx": "2.1.1", "clsx": "catalog:",
"cmdk": "1.1.1", "cmdk": "catalog:",
"color": "^4.2.1", "color": "catalog:",
"crypto-js": "4.2.0", "crypto-js": "catalog:",
"d3-hierarchy": "3.1.2", "d3-hierarchy": "catalog:",
"dayjs": "^1.10.7", "dayjs": "catalog:",
"dompurify": "3.4.0", "dompurify": "catalog:",
"event-source-polyfill": "1.0.31", "event-source-polyfill": "catalog:",
"eventemitter3": "5.0.1", "eventemitter3": "catalog:",
"history": "4.10.1", "history": "catalog:",
"http-proxy-middleware": "4.0.0", "http-proxy-middleware": "catalog:",
"http-status-codes": "2.3.0", "http-status-codes": "catalog:",
"i18next": "^21.6.12", "i18next": "catalog:",
"i18next-browser-languagedetector": "^6.1.3", "i18next-browser-languagedetector": "catalog:",
"i18next-http-backend": "^4.0.0", "i18next-http-backend": "catalog:",
"immer": "11.1.3", "immer": "catalog:",
"jest": "30.2.0", "jest": "catalog:",
"js-base64": "^3.7.2", "js-base64": "catalog:",
"lodash-es": "^4.17.21", "lodash-es": "catalog:",
"lucide-react": "0.498.0", "lucide-react": "catalog:",
"monaco-editor": "0.55.1", "monaco-editor": "catalog:",
"motion": "12.4.13", "motion": "catalog:",
"nuqs": "2.8.8", "nuqs": "catalog:",
"overlayscrollbars": "^2.8.1", "overlayscrollbars": "catalog:",
"overlayscrollbars-react": "^0.5.6", "overlayscrollbars-react": "catalog:",
"papaparse": "5.4.1", "papaparse": "catalog:",
"prop-types": "15.8.1", "prop-types": "catalog:",
"rc-tween-one": "3.0.6", "rc-tween-one": "catalog:",
"react": "19.2.7", "react": "catalog:",
"react-addons-update": "15.6.3", "react-addons-update": "catalog:",
"react-day-picker": "^9.0.0", "react-day-picker": "catalog:",
"react-dnd": "16.0.1", "react-dnd": "catalog:",
"react-dnd-html5-backend": "16.0.1", "react-dnd-html5-backend": "catalog:",
"react-dom": "19.2.7", "react-dom": "catalog:",
"react-drag-listview": "2.0.0", "react-drag-listview": "catalog:",
"react-force-graph-2d": "^1.29.1", "react-force-graph-2d": "catalog:",
"react-full-screen": "1.1.1", "react-full-screen": "catalog:",
"react-grid-layout": "^1.3.4", "react-grid-layout": "catalog:",
"react-helmet-async": "3.0.0", "react-helmet-async": "catalog:",
"react-hook-form": "7.71.2", "react-hook-form": "catalog:",
"react-i18next": "^11.16.1", "react-i18next": "catalog:",
"react-json-tree": "^0.20.0", "react-json-tree": "catalog:",
"react-markdown": "9.0.3", "react-markdown": "catalog:",
"react-native-svg": "npm:[email protected]", "react-native-svg": "npm:[email protected]",
"react-native-web": "0.21.2", "react-native-web": "catalog:",
"react-query": "3.39.3", "react-query": "catalog:",
"react-redux": "9.3.0", "react-redux": "catalog:",
"react-resizable-panels": "^4.0.0", "react-resizable-panels": "catalog:",
"react-rnd": "^10.5.3", "react-rnd": "catalog:",
"react-router-dom": "^5.2.0", "react-router-dom": "catalog:",
"react-router-dom-v5-compat": "6.30.3", "react-router-dom-v5-compat": "catalog:",
"react-syntax-highlighter": "15.5.0", "react-syntax-highlighter": "catalog:",
"react-use": "^17.3.2", "react-use": "catalog:",
"react-virtuoso": "4.0.3", "react-virtuoso": "catalog:",
"redux": "^4.0.5", "redux": "catalog:",
"redux-thunk": "^2.3.0", "redux-thunk": "catalog:",
"rehype-raw": "7.0.0", "rehype-raw": "catalog:",
"remark-gfm": "^4.0.0", "remark-gfm": "catalog:",
"rollup-plugin-visualizer": "7.0.0", "rollup-plugin-visualizer": "catalog:",
"rrule": "2.8.1", "rrule": "catalog:",
"sonner": "2.0.7", "sonner": "catalog:",
"styled-components": "^5.3.11", "styled-components": "catalog:",
"timestamp-nano": "^1.0.0", "timestamp-nano": "catalog:",
"uplot": "1.6.31", "uplot": "catalog:",
"uuid": "^8.3.2", "uuid": "catalog:",
"vaul": "1.1.2", "vaul": "catalog:",
"vite": "npm:[email protected]", "vite": "npm:[email protected]",
"vite-plugin-html": "3.2.2", "vite-plugin-html": "catalog:",
"zod": "4.3.6", "zod": "catalog:",
"zustand": "5.0.11" "zustand": "catalog:"
}, },
"browserslist": { "browserslist": {
"production": [ "production": [
@@ -164,67 +164,67 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.22.11", "@babel/core": "catalog:",
"@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-class-properties": "catalog:",
"@babel/preset-env": "^7.22.14", "@babel/preset-env": "catalog:",
"@babel/preset-react": "^7.12.13", "@babel/preset-react": "catalog:",
"@babel/preset-typescript": "^7.21.4", "@babel/preset-typescript": "catalog:",
"@commitlint/cli": "20.4.4", "@commitlint/cli": "catalog:",
"@commitlint/config-conventional": "20.4.4", "@commitlint/config-conventional": "catalog:",
"@jest/globals": "30.4.1", "@jest/globals": "catalog:",
"@jest/types": "30.2.0", "@jest/types": "catalog:",
"@testing-library/jest-dom": "5.16.5", "@testing-library/jest-dom": "catalog:",
"@testing-library/react": "16.3.2", "@testing-library/react": "catalog:",
"@testing-library/user-event": "14.4.3", "@testing-library/user-event": "catalog:",
"@types/color": "^3.0.3", "@types/color": "catalog:",
"@types/crypto-js": "4.2.2", "@types/crypto-js": "catalog:",
"@types/d3-hierarchy": "1.1.11", "@types/d3-hierarchy": "catalog:",
"@types/event-source-polyfill": "^1.0.0", "@types/event-source-polyfill": "catalog:",
"@types/history": "4.7.11", "@types/history": "catalog:",
"@types/jest": "30.0.0", "@types/jest": "catalog:",
"@types/lodash-es": "^4.17.4", "@types/lodash-es": "catalog:",
"@types/node": "^16.10.3", "@types/node": "catalog:",
"@types/papaparse": "5.3.7", "@types/papaparse": "catalog:",
"@types/react": "19.2.17", "@types/react": "catalog:",
"@types/react-addons-update": "0.14.21", "@types/react-addons-update": "catalog:",
"@types/react-dom": "19.2.3", "@types/react-dom": "catalog:",
"@types/react-grid-layout": "^1.1.2", "@types/react-grid-layout": "catalog:",
"@types/react-resizable": "3.0.3", "@types/react-resizable": "catalog:",
"@types/react-router-dom": "^5.1.6", "@types/react-router-dom": "catalog:",
"@types/react-syntax-highlighter": "15.5.13", "@types/react-syntax-highlighter": "catalog:",
"@types/redux-mock-store": "1.0.4", "@types/redux-mock-store": "catalog:",
"@types/styled-components": "^5.1.4", "@types/styled-components": "catalog:",
"@types/testing-library__jest-dom": "^5.14.5", "@types/testing-library__jest-dom": "catalog:",
"@types/uuid": "^8.3.1", "@types/uuid": "catalog:",
"eslint": "9.39.5", "eslint": "catalog:",
"eslint-plugin-sonarjs": "4.2.0", "eslint-plugin-sonarjs": "catalog:",
"glob": "^13.0.6", "glob": "catalog:",
"husky": "^7.0.4", "husky": "catalog:",
"is-ci": "^3.0.1", "is-ci": "catalog:",
"jest-environment-jsdom": "29.7.0", "jest-environment-jsdom": "catalog:",
"jest-styled-components": "^7.2.0", "jest-styled-components": "catalog:",
"json-schema-to-typescript": "^15.0.4", "json-schema-to-typescript": "catalog:",
"lint-staged": "^17.0.4", "lint-staged": "catalog:",
"msw": "1.3.2", "msw": "catalog:",
"orval": "8.9.1", "orval": "catalog:",
"oxfmt": "0.47.0", "oxfmt": "catalog:",
"oxlint": "1.62.0", "oxlint": "catalog:",
"oxlint-tsgolint": "0.22.1", "oxlint-tsgolint": "catalog:",
"postcss": "8.5.14", "postcss": "catalog:",
"postcss-scss": "4.0.9", "postcss-scss": "catalog:",
"react-resizable": "3.0.4", "react-resizable": "catalog:",
"redux-mock-store": "1.5.4", "redux-mock-store": "catalog:",
"sass": "1.97.3", "sass": "catalog:",
"sharp": "0.34.5", "sharp": "catalog:",
"stylelint": "17.7.0", "stylelint": "catalog:",
"svgo": "4.0.1", "svgo": "catalog:",
"typescript": "7.0.2", "typescript": "catalog:",
"typescript-plugin-css-modules": "5.2.0", "typescript-plugin-css-modules": "catalog:",
"use-sync-external-store": "1.6.0", "use-sync-external-store": "catalog:",
"vite-plugin-checker": "0.12.0", "vite-plugin-checker": "catalog:",
"vite-plugin-compression": "0.5.1", "vite-plugin-compression": "catalog:",
"vite-plugin-image-optimizer": "2.0.3", "vite-plugin-image-optimizer": "catalog:",
"vite-tsconfig-paths": "6.1.1" "vite-tsconfig-paths": "catalog:"
}, },
"lint-staged": { "lint-staged": {
"*.(js|jsx|ts|tsx)": [ "*.(js|jsx|ts|tsx)": [
@@ -240,8 +240,8 @@
}, },
"pnpm": { "pnpm": {
"overrides": { "overrides": {
"@types/react": "19.2.17", "@types/react": "19.2.18",
"@types/react-dom": "19.2.3", "@types/react-dom": "19.2.5",
"debug": "4.3.4", "debug": "4.3.4",
"semver": "7.5.4", "semver": "7.5.4",
"xml2js": "0.5.0", "xml2js": "0.5.0",
+176
View File
@@ -17,3 +17,179 @@ trustPolicyExclude:
# two entries should come back out. # two entries should come back out.
- '@hanzo/*' - '@hanzo/*'
- '@hanzogui/*' - '@hanzogui/*'
overrides:
'zod': '^4.5.2'
catalog:
'@ant-design/colors': '^8.0.1'
'@ant-design/v5-patch-for-react-19': '^1.0.3'
'@babel/core': '^8.0.1'
'@babel/plugin-proposal-class-properties': '^7.18.6'
'@babel/preset-env': '^8.0.2'
'@babel/preset-react': '^8.0.1'
'@babel/preset-typescript': '^8.0.1'
'@codemirror/autocomplete': '^6.20.3'
'@codemirror/lang-javascript': '^6.2.5'
'@codemirror/state': '^6.7.1'
'@codemirror/view': '^6.43.9'
'@commitlint/cli': '^21.2.2'
'@commitlint/config-conventional': '^21.2.2'
'@dnd-kit/core': '^6.3.1'
'@dnd-kit/modifiers': '^9.0.0'
'@dnd-kit/sortable': '^10.0.0'
'@dnd-kit/utilities': '^3.2.2'
'@grafana/data': '^13.2.0'
'@hanzo/font': '1.9.2'
'@hanzo/gui': '8.3.1'
'@hanzo/insights': '1.358.1'
'@hanzo/ui': '8.27.0'
'@jest/globals': '^30.5.0'
'@jest/types': '^30.5.0'
'@monaco-editor/react': '^4.7.0'
'@radix-ui/react-dialog': '^1.1.23'
'@radix-ui/react-dropdown-menu': '^2.1.24'
'@radix-ui/react-popover': '^1.1.23'
'@radix-ui/react-select': '^2.3.7'
'@radix-ui/react-tooltip': '^1.2.16'
'@sentry/react': '^10.72.0'
'@sentry/vite-plugin': '^5.4.0'
'@tanstack/react-table': '^9.2.4'
'@tanstack/react-virtual': '^3.14.10'
'@testing-library/jest-dom': '^7.0.1'
'@testing-library/react': '^16.3.3'
'@testing-library/user-event': '^14.6.6'
'@types/color': '^4.2.1'
'@types/crypto-js': '^4.2.2'
'@types/d3-hierarchy': '^3.1.7'
'@types/event-source-polyfill': '^1.0.5'
'@types/history': '^5.0.0'
'@types/jest': '^30.0.0'
'@types/lodash-es': '^4.17.12'
'@types/node': '26.4.0'
'@types/papaparse': '^5.5.2'
'@types/react': '19.2.18'
'@types/react-addons-update': '^0.14.24'
'@types/react-dom': '19.2.5'
'@types/react-grid-layout': '^2.1.0'
'@types/react-resizable': '^4.0.0'
'@types/react-router-dom': '^5.3.3'
'@types/react-syntax-highlighter': '^15.5.13'
'@types/redux-mock-store': '^1.5.0'
'@types/styled-components': '^5.1.36'
'@types/testing-library__jest-dom': '^6.0.0'
'@types/uuid': '^11.0.0'
'@uiw/codemirror-theme-copilot': '^4.25.11'
'@uiw/codemirror-theme-github': '^4.25.11'
'@uiw/react-codemirror': '^4.25.11'
'@visx/group': '^4.0.0'
'@visx/hierarchy': '^4.0.0'
'@visx/shape': '^4.0.0'
'@visx/tooltip': '^4.0.0'
'@visx/vendor': '^4.0.0'
'@vitejs/plugin-react': '^6.0.2'
'ansi-to-html': '^0.7.2'
'antd': '^6.6.2'
'antd-table-saveas-excel': '^2.2.1'
'antlr4': '^4.13.2'
'axios': '^1.20.0'
'babel-jest': '^30.5.0'
'chart.js': '^4.5.1'
'chartjs-adapter-date-fns': '^3.0.0'
'chartjs-plugin-annotation': '^3.1.0'
'classnames': '^2.5.1'
'clsx': '^2.1.1'
'cmdk': '^1.1.1'
'color': '^5.0.3'
'crypto-js': '^4.2.0'
'd3-hierarchy': '^3.1.2'
'dayjs': '^1.11.23'
'dompurify': '^3.4.14'
'eslint': '^10.9.1'
'eslint-plugin-sonarjs': '^4.2.0'
'event-source-polyfill': '^1.0.31'
'eventemitter3': '^5.0.4'
'glob': '^13.0.6'
'history': '^5.3.0'
'http-proxy-middleware': '^4.2.0'
'http-status-codes': '^2.3.0'
'husky': '^9.1.7'
'i18next': '^26.4.0'
'i18next-browser-languagedetector': '^8.2.1'
'i18next-http-backend': '^4.0.1'
'immer': '^11.1.18'
'is-ci': '^4.1.0'
'jest': '^30.5.0'
'jest-environment-jsdom': '^30.5.0'
'jest-styled-components': '^7.4.0'
'js-base64': '^3.9.3'
'json-schema-to-typescript': '^16.0.0'
'lint-staged': '^17.4.1'
'lodash-es': '^4.18.1'
'lucide-react': '^1.33.0'
'monaco-editor': '^0.56.0'
'motion': '^13.1.1'
'msw': '^2.15.0'
'nuqs': '^2.10.1'
'orval': '^8.27.0'
'overlayscrollbars': '^2.16.0'
'overlayscrollbars-react': '^0.5.6'
'oxfmt': '^0.65.0'
'oxlint': '^1.80.0'
'oxlint-tsgolint': '^7.0.2001'
'papaparse': '^5.7.0'
'postcss': '^8.5.26'
'postcss-scss': '^4.0.9'
'prop-types': '^15.8.1'
'rc-tween-one': '^3.0.6'
'react': '19.2.8'
'react-addons-update': '^15.6.3'
'react-day-picker': '^10.0.1'
'react-dnd': '^16.0.1'
'react-dnd-html5-backend': '^16.0.1'
'react-dom': '19.2.8'
'react-drag-listview': '^2.0.0'
'react-force-graph-2d': '^1.29.1'
'react-full-screen': '^1.1.1'
'react-grid-layout': '^2.2.4'
'react-helmet-async': '^3.0.0'
'react-hook-form': '^7.86.0'
'react-i18next': '^17.0.12'
'react-json-tree': '^0.20.0'
'react-markdown': '^10.1.0'
'react-native-web': '^0.21.2'
'react-query': '^3.39.3'
'react-redux': '^9.3.0'
'react-resizable': '^4.0.2'
'react-resizable-panels': '^2.1.9'
'react-rnd': '^10.5.3'
'react-router-dom': '^7.18.3'
'react-router-dom-v5-compat': '^6.30.6'
'react-syntax-highlighter': '^16.1.1'
'react-use': '^17.6.1'
'react-virtuoso': '^4.18.12'
'redux': '^5.0.1'
'redux-mock-store': '^1.5.5'
'redux-thunk': '^3.1.0'
'rehype-raw': '^7.0.0'
'remark-gfm': '^4.0.1'
'rollup-plugin-visualizer': '^7.1.1'
'rrule': '^2.8.1'
'sass': '^1.103.1'
'sharp': '^0.35.4'
'sonner': '^2.0.8'
'styled-components': '^6.5.3'
'stylelint': '^17.14.1'
'svgo': '^4.1.0'
'timestamp-nano': '^1.0.1'
'typescript': '7.0.2'
'typescript-plugin-css-modules': '^5.2.0'
'uplot': '^1.6.32'
'use-sync-external-store': '^1.6.0'
'uuid': '^14.0.2'
'vaul': '^1.1.2'
'vite-plugin-checker': '^0.14.5'
'vite-plugin-compression': '^0.5.1'
'vite-plugin-html': '^3.2.2'
'vite-plugin-image-optimizer': '^2.0.3'
'vite-tsconfig-paths': '^6.1.1'
'zod': '^4.5.2'
'zustand': '^5.0.15'
-8
View File
@@ -36,14 +36,6 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
// The "sqlite" database/sql driver is registered exactly once by the sqlstore
// provider (pkg/sqlstore/sqlitesqlstore, which this package transitively
// imports and which must import modernc for the *sqlite.Error type). A second
// blank _ "modernc.org/sqlite" here was redundant, and re-pointing it at
// github.com/hanzoai/sqlite would double-register "sqlite" under CGO_ENABLED=1
// (the fork's cgo backend Register()s mattn while modernc's init Register()s
// modernc) — the exact "Register called twice" panic. One registration site.
"github.com/hanzoai/o11y/pkg/contextlinks" "github.com/hanzoai/o11y/pkg/contextlinks"
traceFunnelsModule "github.com/hanzoai/o11y/pkg/modules/tracefunnel" traceFunnelsModule "github.com/hanzoai/o11y/pkg/modules/tracefunnel"
"github.com/hanzoai/o11y/pkg/query-service/agentConf" "github.com/hanzoai/o11y/pkg/query-service/agentConf"
+11 -11
View File
@@ -11,16 +11,16 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// TestDriverRegisteredOnce proves the "sqlite" database/sql driver is registered // TestDriverRegisteredOnce opens the provider and drives the "sqlite" driver name
// exactly once — via this provider's modernc import — and opens cleanly. It is the // end to end, under whichever CGO mode go test runs.
// guard for removing the now-redundant blank _ "modernc.org/sqlite" from //
// pkg/query-service/app/http_handler.go: registration must survive that removal, // It catches the two ways this provider regresses. A duplicate
// and pointing that blank import at github.com/hanzoai/sqlite instead would // sql.Register("sqlite") panics during init, so the binary cannot reach the body
// double-register "sqlite" under CGO_ENABLED=1 (the fork's cgo backend Register()s // below if anything in the graph claims that name twice — which is what importing
// mattn while modernc's init Register()s modernc) and panic. Opening the provider // a backend directly alongside the hanzoai/sqlite facade does under CGO_ENABLED=1,
// here — under whatever CGO mode the test runs — fails loudly if either regression // where the facade already registers the name against csqlite. And the pragma
// returns. It also asserts the DSN pragmas take effect (journal_mode=wal, // assertions read back through the driver, so a DSN in the other backend's dialect
// busy_timeout>0) through the driver. // is caught here rather than silently ignored at open.
func TestDriverRegisteredOnce(t *testing.T) { func TestDriverRegisteredOnce(t *testing.T) {
dbPath := filepath.Join(t.TempDir(), "o11y.db") dbPath := filepath.Join(t.TempDir(), "o11y.db")
store, err := New(context.Background(), factorytest.NewSettings(), sqlstore.Config{ store, err := New(context.Background(), factorytest.NewSettings(), sqlstore.Config{
@@ -43,7 +43,7 @@ func TestDriverRegisteredOnce(t *testing.T) {
var journalMode string var journalMode string
require.NoError(t, sqldb.QueryRow("PRAGMA journal_mode").Scan(&journalMode)) require.NoError(t, sqldb.QueryRow("PRAGMA journal_mode").Scan(&journalMode))
require.Equal(t, "wal", journalMode, "journal_mode not applied — modernc _pragma DSN form not honored") require.Equal(t, "wal", journalMode, "journal_mode not applied — PragmaDSN emitted a form the linked backend ignores")
var busyTimeout int var busyTimeout int
require.NoError(t, sqldb.QueryRow("PRAGMA busy_timeout").Scan(&busyTimeout)) require.NoError(t, sqldb.QueryRow("PRAGMA busy_timeout").Scan(&busyTimeout))
+6 -5
View File
@@ -13,11 +13,12 @@ import (
"github.com/uptrace/bun" "github.com/uptrace/bun"
"github.com/uptrace/bun/dialect/sqlitedialect" "github.com/uptrace/bun/dialect/sqlitedialect"
// hanzoai/sqlite is the one dual-backend driver: importing it registers the // hanzoai/sqlite names a facade, not an engine. Importing it registers the
// "sqlite" database/sql driver (mattn/SQLCipher under cgo, modernc pure-Go // "sqlite" database/sql driver exactly once — SQLCipher/csqlite under cgo,
// otherwise) AND exposes backend-neutral constraint-error classification, so // pure-Go otherwise — and supplies the backend-neutral pragma and
// this package no longer imports modernc directly (which would double-register // constraint-error primitives used below. Naming an engine here instead would
// "sqlite" in the cgo cloud binary). // claim that driver name a second time in the cgo cloud binary, panicking at
// init, and would pin this package to one backend's DSN dialect.
"github.com/hanzoai/sqlite" "github.com/hanzoai/sqlite"
) )
+35
View File
@@ -0,0 +1,35 @@
package telemetrymetadata
import "testing"
// The DDL production actually serves for event.span, verbatim from
// SHOW CREATE TABLE (real newlines restored).
const spanDDL = "CREATE TABLE event.span\n(\n `org` LowCardinality(String),\n `time` DateTime64(9) CODEC(DoubleDelta, ZSTD(1)),\n `ingested_at` DateTime64(3) DEFAULT now64(3) CODEC(DoubleDelta, ZSTD(1)),\n `id` String CODEC(ZSTD(1)),\n `name` String CODEC(ZSTD(1)),\n `kind` LowCardinality(String),\n `product` LowCardinality(String),\n `session_id` String CODEC(ZSTD(1)),\n `distinct_id` String CODEC(ZSTD(1)),\n `anonymous_id` String CODEC(ZSTD(1)),\n `person_id` String CODEC(ZSTD(1)),\n `url` String CODEC(ZSTD(1)),\n `path` String CODEC(ZSTD(1)),\n `attributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n `el` Tuple(\n label String,\n role LowCardinality(String),\n testid String,\n name String,\n component LowCardinality(String),\n path Array(String)) CODEC(ZSTD(1)),\n `host` LowCardinality(String) DEFAULT domain(url),\n `service` LowCardinality(String),\n `trace_id` String CODEC(ZSTD(1)),\n `span_id` String CODEC(ZSTD(1)),\n `parent` String CODEC(ZSTD(1)),\n `duration` UInt64 CODEC(T64, ZSTD(1)),\n `status` LowCardinality(String),\n `resource_fingerprint` String CODEC(ZSTD(1)),\n `ts_bucket_start` UInt64 MATERIALIZED intDiv(toUnixTimestamp(time), 1800) * 1800 CODEC(DoubleDelta, ZSTD(1)),\n INDEX by_time time TYPE minmax GRANULARITY 1,\n INDEX by_service service TYPE set(0) GRANULARITY 4,\n INDEX by_duration duration TYPE minmax GRANULARITY 1\n)\nENGINE = ReplacingMergeTree(ingested_at)\nPARTITION BY toDate(ingested_at)\nORDER BY (org, trace_id, time, id)\nTTL toDateTime(ingested_at) + toIntervalDay(30)\nSETTINGS index_granularity = 8192, ttl_only_drop_parts = 1"
func TestReproSpanDDL(t *testing.T) {
_, err := ExtractFieldKeysFromTblStatement(spanDDL)
if err != nil {
t.Fatalf("FULL span DDL failed: %v", err)
}
t.Log("full span DDL parsed OK")
}
// Bisect: the same DDL with the named-Tuple column removed.
func TestReproSpanDDLNoTuple(t *testing.T) {
ddl := "CREATE TABLE event.span\n(\n `org` LowCardinality(String),\n `attributes` Map(LowCardinality(String), String) CODEC(ZSTD(1)),\n `host` LowCardinality(String) DEFAULT domain(url)\n)\nENGINE = ReplacingMergeTree(ingested_at)\nORDER BY (org)"
_, err := ExtractFieldKeysFromTblStatement(ddl)
if err != nil {
t.Fatalf("no-tuple DDL failed: %v", err)
}
t.Log("no-tuple DDL parsed OK")
}
// Bisect: just the named Tuple column.
func TestReproTupleOnly(t *testing.T) {
ddl := "CREATE TABLE event.span\n(\n `org` LowCardinality(String),\n `el` Tuple(\n label String,\n role LowCardinality(String),\n path Array(String)) CODEC(ZSTD(1))\n)\nENGINE = ReplacingMergeTree(ingested_at)\nORDER BY (org)"
_, err := ExtractFieldKeysFromTblStatement(ddl)
if err != nil {
t.Fatalf("tuple-only DDL failed: %v", err)
}
t.Log("tuple-only DDL parsed OK")
}
+3 -3
View File
@@ -1,7 +1,7 @@
{ {
"name": "@hanzo/o11y", "name": "@hanzo/o11y",
"version": "0.1.0", "version": "0.1.0",
"description": "Hanzo o11y SDK \u2014 traces over ZAP. No OpenTelemetry, no OTLP, no gRPC.", "description": "Hanzo o11y SDK — traces over ZAP. No OpenTelemetry, no OTLP, no gRPC.",
"type": "module", "type": "module",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -22,8 +22,8 @@
"@zap-proto/zap": "^1.6.0" "@zap-proto/zap": "^1.6.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.0.0", "@types/node": "26.4.0",
"typescript": "^5.6.0" "typescript": "7.0.2"
}, },
"engines": { "engines": {
"node": ">=18.12.0" "node": ">=18.12.0"
+8 -8
View File
@@ -32,14 +32,14 @@
"author": "", "author": "",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.57.0-alpha-2025-10-09", "@playwright/test": "^1.62.1",
"@types/node": "^20.0.0", "@types/node": "26.4.0",
"dotenv": "^16.0.0", "dotenv": "^17.4.2",
"eslint-plugin-playwright": "^2.10.2", "eslint-plugin-playwright": "^2.11.0",
"oxfmt": "^0.41.0", "oxfmt": "^0.65.0",
"oxlint": "^1.59.0", "oxlint": "^1.80.0",
"oxlint-tsgolint": "^0.20.0", "oxlint-tsgolint": "^7.0.2001",
"typescript": "^5.0.0" "typescript": "7.0.2"
}, },
"engines": { "engines": {
"node": ">=18.0.0", "node": ">=18.0.0",