tempest-react-sdk 0.57.0 → 0.58.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/bin/lib/icons/generate.test.mjs +4 -4
- package/dist/br/geocode.cjs +1 -1
- package/dist/br/geocode.cjs.map +1 -1
- package/dist/br/geocode.js +1 -1
- package/dist/br/geocode.js.map +1 -1
- package/dist/capture/use-barcode-scanner.cjs +1 -1
- package/dist/capture/use-barcode-scanner.cjs.map +1 -1
- package/dist/capture/use-barcode-scanner.js +1 -1
- package/dist/capture/use-barcode-scanner.js.map +1 -1
- package/dist/components/AIChat/AIChat.cjs +1 -1
- package/dist/components/AIChat/AIChat.cjs.map +1 -1
- package/dist/components/AIChat/AIChat.js +1 -1
- package/dist/components/AIChat/AIChat.js.map +1 -1
- package/dist/components/AIChat/AIChatTurn.cjs +1 -1
- package/dist/components/AIChat/AIChatTurn.cjs.map +1 -1
- package/dist/components/AIChat/AIChatTurn.js +1 -1
- package/dist/components/AIChat/AIChatTurn.js.map +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.cjs +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.cjs.map +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.js +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.js.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.cjs +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.cjs.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.js +2 -2
- package/dist/components/AudioPlayer/AudioPlayer.js.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.cjs +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.cjs.map +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.js +1 -1
- package/dist/components/AudioRecorder/AudioRecorder.js.map +1 -1
- package/dist/components/Chat/Chat.cjs +1 -1
- package/dist/components/Chat/Chat.cjs.map +1 -1
- package/dist/components/Chat/Chat.js +1 -1
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/FilterBar/FilterBar.cjs +1 -1
- package/dist/components/FilterBar/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar/FilterBar.js +1 -1
- package/dist/components/FilterBar/FilterBar.js.map +1 -1
- package/dist/components/FilterBar/filter-apply.cjs +1 -1
- package/dist/components/FilterBar/filter-apply.cjs.map +1 -1
- package/dist/components/FilterBar/filter-apply.js +1 -1
- package/dist/components/FilterBar/filter-apply.js.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.cjs +1 -1
- package/dist/components/ImageCropper/ImageCropper.cjs.map +1 -1
- package/dist/components/ImageCropper/ImageCropper.js +1 -1
- package/dist/components/ImageCropper/ImageCropper.js.map +1 -1
- package/dist/components/VideoPlayer/VideoPlayer.cjs +1 -1
- package/dist/components/VideoPlayer/VideoPlayer.cjs.map +1 -1
- package/dist/components/VideoPlayer/VideoPlayer.js +2 -2
- package/dist/components/VideoPlayer/VideoPlayer.js.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.cjs +1 -1
- package/dist/components/VirtualTable/VirtualTable.cjs.map +1 -1
- package/dist/components/VirtualTable/VirtualTable.js +1 -1
- package/dist/components/VirtualTable/VirtualTable.js.map +1 -1
- package/dist/feature-flags/growthbook-adapter.cjs +1 -1
- package/dist/feature-flags/growthbook-adapter.cjs.map +1 -1
- package/dist/feature-flags/growthbook-adapter.js +1 -1
- package/dist/feature-flags/growthbook-adapter.js.map +1 -1
- package/dist/hooks/use-focus-trap.cjs +1 -1
- package/dist/hooks/use-focus-trap.cjs.map +1 -1
- package/dist/hooks/use-focus-trap.js +1 -1
- package/dist/hooks/use-focus-trap.js.map +1 -1
- package/dist/hooks/use-push-to-talk.cjs +1 -1
- package/dist/hooks/use-push-to-talk.cjs.map +1 -1
- package/dist/hooks/use-push-to-talk.js +1 -1
- package/dist/hooks/use-push-to-talk.js.map +1 -1
- package/dist/http/resumable-upload.cjs +1 -1
- package/dist/http/resumable-upload.cjs.map +1 -1
- package/dist/http/resumable-upload.js +1 -1
- package/dist/http/resumable-upload.js.map +1 -1
- package/dist/icons/generated/aliases.cjs +1 -1
- package/dist/icons/generated/aliases.cjs.map +1 -1
- package/dist/icons/generated/aliases.js +1 -0
- package/dist/icons/generated/aliases.js.map +1 -1
- package/dist/icons/generated/icon-names.cjs +1 -1
- package/dist/icons/generated/icon-names.cjs.map +1 -1
- package/dist/icons/generated/icon-names.js +1 -1
- package/dist/icons/generated/icon-names.js.map +1 -1
- package/dist/icons/generated/loaders.cjs +1 -1
- package/dist/icons/generated/loaders.cjs.map +1 -1
- package/dist/icons/generated/loaders.js +48 -42
- package/dist/icons/generated/loaders.js.map +1 -1
- package/dist/icons/generated/shard-02.cjs +1 -1
- package/dist/icons/generated/shard-02.cjs.map +1 -1
- package/dist/icons/generated/shard-02.js +20 -20
- package/dist/icons/generated/shard-02.js.map +1 -1
- package/dist/icons/generated/shard-03.cjs +1 -1
- package/dist/icons/generated/shard-03.cjs.map +1 -1
- package/dist/icons/generated/shard-03.js +41 -41
- package/dist/icons/generated/shard-03.js.map +1 -1
- package/dist/icons/generated/shard-04.cjs +1 -1
- package/dist/icons/generated/shard-04.cjs.map +1 -1
- package/dist/icons/generated/shard-04.js +41 -41
- package/dist/icons/generated/shard-04.js.map +1 -1
- package/dist/icons/generated/shard-05.cjs +1 -1
- package/dist/icons/generated/shard-05.cjs.map +1 -1
- package/dist/icons/generated/shard-05.js +41 -41
- package/dist/icons/generated/shard-05.js.map +1 -1
- package/dist/icons/generated/shard-06.cjs +1 -1
- package/dist/icons/generated/shard-06.cjs.map +1 -1
- package/dist/icons/generated/shard-06.js +41 -41
- package/dist/icons/generated/shard-06.js.map +1 -1
- package/dist/icons/generated/shard-07.cjs +1 -1
- package/dist/icons/generated/shard-07.cjs.map +1 -1
- package/dist/icons/generated/shard-07.js +41 -41
- package/dist/icons/generated/shard-07.js.map +1 -1
- package/dist/icons/generated/shard-08.cjs +1 -1
- package/dist/icons/generated/shard-08.cjs.map +1 -1
- package/dist/icons/generated/shard-08.js +41 -41
- package/dist/icons/generated/shard-08.js.map +1 -1
- package/dist/icons/generated/shard-09.cjs +1 -1
- package/dist/icons/generated/shard-09.cjs.map +1 -1
- package/dist/icons/generated/shard-09.js +41 -41
- package/dist/icons/generated/shard-09.js.map +1 -1
- package/dist/icons/generated/shard-10.cjs +1 -1
- package/dist/icons/generated/shard-10.cjs.map +1 -1
- package/dist/icons/generated/shard-10.js +41 -41
- package/dist/icons/generated/shard-10.js.map +1 -1
- package/dist/icons/generated/shard-11.cjs +1 -1
- package/dist/icons/generated/shard-11.cjs.map +1 -1
- package/dist/icons/generated/shard-11.js +41 -41
- package/dist/icons/generated/shard-11.js.map +1 -1
- package/dist/icons/generated/shard-12.cjs +1 -1
- package/dist/icons/generated/shard-12.cjs.map +1 -1
- package/dist/icons/generated/shard-12.js +41 -41
- package/dist/icons/generated/shard-12.js.map +1 -1
- package/dist/icons/generated/shard-13.cjs +1 -1
- package/dist/icons/generated/shard-13.cjs.map +1 -1
- package/dist/icons/generated/shard-13.js +41 -41
- package/dist/icons/generated/shard-13.js.map +1 -1
- package/dist/icons/generated/shard-14.cjs +1 -1
- package/dist/icons/generated/shard-14.cjs.map +1 -1
- package/dist/icons/generated/shard-14.js +41 -41
- package/dist/icons/generated/shard-14.js.map +1 -1
- package/dist/icons/generated/shard-15.cjs +1 -1
- package/dist/icons/generated/shard-15.cjs.map +1 -1
- package/dist/icons/generated/shard-15.js +41 -41
- package/dist/icons/generated/shard-15.js.map +1 -1
- package/dist/icons/generated/shard-16.cjs +1 -1
- package/dist/icons/generated/shard-16.cjs.map +1 -1
- package/dist/icons/generated/shard-16.js +41 -41
- package/dist/icons/generated/shard-16.js.map +1 -1
- package/dist/icons/generated/shard-17.cjs +1 -1
- package/dist/icons/generated/shard-17.cjs.map +1 -1
- package/dist/icons/generated/shard-17.js +41 -41
- package/dist/icons/generated/shard-17.js.map +1 -1
- package/dist/icons/generated/shard-18.cjs +1 -1
- package/dist/icons/generated/shard-18.cjs.map +1 -1
- package/dist/icons/generated/shard-18.js +41 -41
- package/dist/icons/generated/shard-18.js.map +1 -1
- package/dist/icons/generated/shard-19.cjs +1 -1
- package/dist/icons/generated/shard-19.cjs.map +1 -1
- package/dist/icons/generated/shard-19.js +41 -41
- package/dist/icons/generated/shard-19.js.map +1 -1
- package/dist/icons/generated/shard-20.cjs +1 -1
- package/dist/icons/generated/shard-20.cjs.map +1 -1
- package/dist/icons/generated/shard-20.js +41 -41
- package/dist/icons/generated/shard-20.js.map +1 -1
- package/dist/icons/generated/shard-21.cjs +1 -1
- package/dist/icons/generated/shard-21.cjs.map +1 -1
- package/dist/icons/generated/shard-21.js +41 -41
- package/dist/icons/generated/shard-21.js.map +1 -1
- package/dist/icons/generated/shard-22.cjs +1 -1
- package/dist/icons/generated/shard-22.cjs.map +1 -1
- package/dist/icons/generated/shard-22.js +41 -41
- package/dist/icons/generated/shard-22.js.map +1 -1
- package/dist/icons/generated/shard-23.cjs +1 -1
- package/dist/icons/generated/shard-23.cjs.map +1 -1
- package/dist/icons/generated/shard-23.js +41 -41
- package/dist/icons/generated/shard-23.js.map +1 -1
- package/dist/icons/generated/shard-24.cjs +1 -1
- package/dist/icons/generated/shard-24.cjs.map +1 -1
- package/dist/icons/generated/shard-24.js +41 -41
- package/dist/icons/generated/shard-24.js.map +1 -1
- package/dist/icons/generated/shard-25.cjs +1 -1
- package/dist/icons/generated/shard-25.cjs.map +1 -1
- package/dist/icons/generated/shard-25.js +41 -41
- package/dist/icons/generated/shard-25.js.map +1 -1
- package/dist/icons/generated/shard-26.cjs +1 -1
- package/dist/icons/generated/shard-26.cjs.map +1 -1
- package/dist/icons/generated/shard-26.js +41 -41
- package/dist/icons/generated/shard-26.js.map +1 -1
- package/dist/icons/generated/shard-27.cjs +1 -1
- package/dist/icons/generated/shard-27.cjs.map +1 -1
- package/dist/icons/generated/shard-27.js +41 -41
- package/dist/icons/generated/shard-27.js.map +1 -1
- package/dist/icons/generated/shard-28.cjs +1 -1
- package/dist/icons/generated/shard-28.cjs.map +1 -1
- package/dist/icons/generated/shard-28.js +41 -41
- package/dist/icons/generated/shard-28.js.map +1 -1
- package/dist/icons/generated/shard-29.cjs +1 -1
- package/dist/icons/generated/shard-29.cjs.map +1 -1
- package/dist/icons/generated/shard-29.js +41 -41
- package/dist/icons/generated/shard-29.js.map +1 -1
- package/dist/icons/generated/shard-30.cjs +1 -1
- package/dist/icons/generated/shard-30.cjs.map +1 -1
- package/dist/icons/generated/shard-30.js +41 -41
- package/dist/icons/generated/shard-30.js.map +1 -1
- package/dist/icons/generated/shard-31.cjs +1 -1
- package/dist/icons/generated/shard-31.cjs.map +1 -1
- package/dist/icons/generated/shard-31.js +41 -41
- package/dist/icons/generated/shard-31.js.map +1 -1
- package/dist/icons/generated/shard-32.cjs +1 -1
- package/dist/icons/generated/shard-32.cjs.map +1 -1
- package/dist/icons/generated/shard-32.js +41 -41
- package/dist/icons/generated/shard-32.js.map +1 -1
- package/dist/icons/generated/shard-33.cjs +1 -1
- package/dist/icons/generated/shard-33.cjs.map +1 -1
- package/dist/icons/generated/shard-33.js +41 -41
- package/dist/icons/generated/shard-33.js.map +1 -1
- package/dist/icons/generated/shard-34.cjs +1 -1
- package/dist/icons/generated/shard-34.cjs.map +1 -1
- package/dist/icons/generated/shard-34.js +41 -41
- package/dist/icons/generated/shard-34.js.map +1 -1
- package/dist/icons/generated/shard-35.cjs +1 -1
- package/dist/icons/generated/shard-35.cjs.map +1 -1
- package/dist/icons/generated/shard-35.js +41 -41
- package/dist/icons/generated/shard-35.js.map +1 -1
- package/dist/icons/generated/shard-36.cjs +1 -1
- package/dist/icons/generated/shard-36.cjs.map +1 -1
- package/dist/icons/generated/shard-36.js +41 -41
- package/dist/icons/generated/shard-36.js.map +1 -1
- package/dist/icons/generated/shard-37.cjs +1 -1
- package/dist/icons/generated/shard-37.cjs.map +1 -1
- package/dist/icons/generated/shard-37.js +41 -41
- package/dist/icons/generated/shard-37.js.map +1 -1
- package/dist/icons/generated/shard-38.cjs +1 -1
- package/dist/icons/generated/shard-38.cjs.map +1 -1
- package/dist/icons/generated/shard-38.js +41 -41
- package/dist/icons/generated/shard-38.js.map +1 -1
- package/dist/icons/generated/shard-39.cjs +1 -1
- package/dist/icons/generated/shard-39.cjs.map +1 -1
- package/dist/icons/generated/shard-39.js +41 -41
- package/dist/icons/generated/shard-39.js.map +1 -1
- package/dist/icons/generated/shard-40.cjs +1 -1
- package/dist/icons/generated/shard-40.cjs.map +1 -1
- package/dist/icons/generated/shard-40.js +41 -41
- package/dist/icons/generated/shard-40.js.map +1 -1
- package/dist/icons/generated/shard-41.cjs +1 -1
- package/dist/icons/generated/shard-41.cjs.map +1 -1
- package/dist/icons/generated/shard-41.js +41 -41
- package/dist/icons/generated/shard-41.js.map +1 -1
- package/dist/icons/generated/shard-42.cjs +1 -1
- package/dist/icons/generated/shard-42.cjs.map +1 -1
- package/dist/icons/generated/shard-42.js +41 -41
- package/dist/icons/generated/shard-42.js.map +1 -1
- package/dist/icons/generated/shard-43.cjs +1 -1
- package/dist/icons/generated/shard-43.cjs.map +1 -1
- package/dist/icons/generated/shard-43.js +41 -41
- package/dist/icons/generated/shard-43.js.map +1 -1
- package/dist/icons/generated/shard-44.cjs +1 -1
- package/dist/icons/generated/shard-44.cjs.map +1 -1
- package/dist/icons/generated/shard-44.js +43 -10
- package/dist/icons/generated/shard-44.js.map +1 -1
- package/dist/icons/generated/shard-45.cjs +2 -0
- package/dist/icons/generated/shard-45.cjs.map +1 -0
- package/dist/icons/generated/shard-45.js +15 -0
- package/dist/icons/generated/shard-45.js.map +1 -0
- package/dist/icons/material-symbols.cjs +1 -1
- package/dist/icons/material-symbols.cjs.map +1 -1
- package/dist/icons/material-symbols.js +3 -3
- package/dist/icons/material-symbols.js.map +1 -1
- package/dist/icons.d.ts +4 -4
- package/dist/query/foreign-client-warning.cjs +1 -1
- package/dist/query/foreign-client-warning.cjs.map +1 -1
- package/dist/query/foreign-client-warning.js +1 -1
- package/dist/query/foreign-client-warning.js.map +1 -1
- package/dist/utils/json-frame.cjs +1 -1
- package/dist/utils/json-frame.cjs.map +1 -1
- package/dist/utils/json-frame.js +1 -1
- package/dist/utils/json-frame.js.map +1 -1
- package/dist/vision/core/providers.cjs +1 -1
- package/dist/vision/core/providers.cjs.map +1 -1
- package/dist/vision/core/providers.js +22 -3
- package/dist/vision/core/providers.js.map +1 -1
- package/dist/vision/core/session.cjs +1 -1
- package/dist/vision/core/session.cjs.map +1 -1
- package/dist/vision/core/session.js +22 -15
- package/dist/vision/core/session.js.map +1 -1
- package/dist/vision/fusion.cjs.map +1 -1
- package/dist/vision/fusion.js.map +1 -1
- package/dist/vision/index.cjs +1 -1
- package/dist/vision/index.cjs.map +1 -1
- package/dist/vision/index.js +17 -16
- package/dist/vision/index.js.map +1 -1
- package/dist/vision/normalization.cjs +2 -0
- package/dist/vision/normalization.cjs.map +1 -0
- package/dist/vision/normalization.js +49 -0
- package/dist/vision/normalization.js.map +1 -0
- package/dist/vision/results.cjs +1 -1
- package/dist/vision/results.cjs.map +1 -1
- package/dist/vision/results.js +8 -2
- package/dist/vision/results.js.map +1 -1
- package/dist/vision/tasks/classifier.cjs +1 -1
- package/dist/vision/tasks/classifier.cjs.map +1 -1
- package/dist/vision/tasks/classifier.js +36 -32
- package/dist/vision/tasks/classifier.js.map +1 -1
- package/dist/vision.cjs +1 -1
- package/dist/vision.d.ts +218 -13
- package/dist/vision.js +19 -18
- package/dist/vite/tempest-pwa-manifest.cjs +1 -1
- package/dist/vite/tempest-pwa-manifest.cjs.map +1 -1
- package/dist/vite/tempest-pwa-manifest.js +1 -1
- package/dist/vite/tempest-pwa-manifest.js.map +1 -1
- package/dist/webrtc/peer-link.cjs +1 -1
- package/dist/webrtc/peer-link.cjs.map +1 -1
- package/dist/webrtc/peer-link.js +1 -1
- package/dist/webrtc/peer-link.js.map +1 -1
- package/dist/webrtc/peer-mesh.cjs +1 -1
- package/dist/webrtc/peer-mesh.cjs.map +1 -1
- package/dist/webrtc/peer-mesh.js +1 -1
- package/dist/webrtc/peer-mesh.js.map +1 -1
- package/dist/ws/create-web-socket.cjs +1 -1
- package/dist/ws/create-web-socket.cjs.map +1 -1
- package/dist/ws/create-web-socket.js +1 -1
- package/dist/ws/create-web-socket.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"classifier.js","names":[],"sources":["../../../src/vision/tasks/classifier.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Image classification task using ONNX Runtime Web.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\nimport { type ModelSource, type OrtSessionOptions, OrtSession } from \"../core/session\";\nimport { SpeedTimer } from \"../core/timing\";\nimport { type ImageInput, loadImage } from \"../io/image\";\nimport { classificationNumClasses, resolveInputSize } from \"../core/graph\";\nimport { modelNames } from \"../core/metadata\";\nimport { type LabelSpec, resolveLabels } from \"../labels\";\nimport { softmax, topK } from \"../postprocess/classification\";\nimport { toFloat32Tensor } from \"../preprocess/image\";\nimport { ResizePipeline, zeroTensorData } from \"../preprocess/pipeline\";\nimport { ClassificationResults, Probs } from \"../results\";\nimport { VisionTask } from \"./base\";\nimport { type ClassProbability, type ClassificationResult, type RGBImage } from \"../types\";\n\nconst IMAGENET_MEAN: readonly [number, number, number] = [0.485, 0.456, 0.406];\nconst IMAGENET_STD: readonly [number, number, number] = [0.229, 0.224, 0.225];\n\nexport interface ClassifierOptions extends OrtSessionOptions {\n /**\n * Class label spec — see {@link resolveLabels}.\n *\n * Optional: when omitted, the names the export baked into the model are used\n * (Ultralytics writes them as `names` in the metadata map). Only when the\n * model carries none does this fall back to generated `class_<id>` labels.\n * Passing a spec always wins, for a model whose names are wrong or absent.\n */\n readonly labels?: LabelSpec;\n /**\n * Number of classes the model can predict.\n *\n * Optional: inferred from the classification head's declared output shape\n * `(B, nc)`. Pass it to validate that the supplied labels match the model.\n */\n readonly numClasses?: number;\n /**\n * Model input `[width, height]` in pixels.\n *\n * Only used when the model's graph leaves its spatial axes dynamic: a graph\n * that declares a static size always wins, since that is the only shape ONNX\n * Runtime will accept. Defaults to `[224, 224]`.\n */\n readonly inputSize?: readonly [number, number];\n /** Per-channel RGB mean used for normalization. Defaults to ImageNet. */\n readonly mean?: readonly [number, number, number];\n /** Per-channel RGB standard deviation. Defaults to ImageNet. */\n readonly std?: readonly [number, number, number];\n /**\n * If `true` (default), apply softmax to the raw model output. Set to\n * `false` for models whose final layer already produces a probability\n * distribution.\n */\n readonly applySoftmax?: boolean;\n}\n\nexport interface ClassifierPredictOptions {\n /**\n * If set, the per-class probability list in `results[0].result.probabilities`\n * is truncated to the top-K entries. The bulk `probs` view always exposes\n * the full vector.\n */\n readonly topK?: number;\n}\n\n/**\n * Image classifier wrapping an ONNX model with ImageNet-style preprocessing.\n *\n * `predict()` returns `Promise<ClassificationResults[]>` (length 1 for a\n * single image), mirroring Ultralytics' API. The envelope exposes a `probs`\n * collection (`top1`, `top1conf`, `top5`, `top5conf`, `data`) plus the\n * legacy per-class probability list with names already resolved.\n *\n * Defaults: 224×224 RGB input, `float32` normalized with ImageNet mean/std,\n * NCHW layout, batch size 1, softmax applied to the raw output.\n *\n * @example\n * ```typescript\n * const clf = await Classifier.create(\"/models/resnet50.onnx\", {\n * labels: [\"tench\", \"goldfish\", ...] // 1000 ImageNet labels\n * });\n * const r = (await clf.predict(\"/images/dog.jpg\"))[0];\n * console.log(r.cls, r.conf, r.name);\n * console.log(r.probs.top5, r.probs.top5conf);\n * ```\n */\nexport class Classifier extends VisionTask {\n private constructor(\n session: OrtSession,\n private readonly _labels: readonly string[],\n private readonly _names: Readonly<Record<number, string>>,\n private readonly _inputSize: readonly [number, number],\n private readonly _mean: readonly [number, number, number],\n private readonly _std: readonly [number, number, number],\n private readonly _applySoftmax: boolean,\n ) {\n super(session);\n }\n\n private _pipelineCache: ResizePipeline | null = null;\n\n /**\n * Run the model once on a zero tensor, paying one-time costs up front.\n *\n * The first inference of a session is not representative: WebGPU compiles its\n * shaders on it and the WASM backend faults in its arenas. Calling this while\n * a loading spinner is still up moves that cost somewhere the user is already\n * waiting — which matters most for a classifier running as the last step of\n * an on-device analysis, where the delay lands right before the answer shows.\n *\n * @param runs How many warm-up inferences to run. One is enough for WASM;\n * WebGPU sometimes settles on the second.\n */\n async warmup(runs: number = 1): Promise<void> {\n const [tw, th] = this._inputSize;\n for (let i = 0; i < runs; i++) {\n const tensor = toFloat32Tensor(zeroTensorData(tw, th), [1, 3, th, tw]);\n await this._session.run({ [this._session.inputName]: tensor });\n }\n }\n\n /**\n * The fused preprocessing pipeline, built on first use.\n *\n * Lazily, because constructing it reserves the output buffer: a task built in\n * an environment without a canvas implementation stays constructible, and only\n * fails if it is actually asked to preprocess something.\n */\n private get _pipeline(): ResizePipeline {\n if (this._pipelineCache === null) {\n const [tw, th] = this._inputSize;\n this._pipelineCache = new ResizePipeline(tw, th, this._mean, this._std);\n }\n return this._pipelineCache;\n }\n\n /** Load the model and resolve labels. */\n static async create(model: ModelSource, options: ClassifierOptions = {}): Promise<Classifier> {\n const session = await OrtSession.create(model, options);\n const numClasses =\n options.numClasses ?? classificationNumClasses(session.outputShape) ?? undefined;\n const labels = resolveLabels(options.labels ?? modelNames(session.metadata), {\n numClasses,\n });\n const names: Record<number, string> = {};\n for (let i = 0; i < labels.length; i++) {\n names[i] = labels[i] as string;\n }\n return new Classifier(\n session,\n labels,\n names,\n resolveInputSize({\n graphShape: session.inputShape,\n requested: options.inputSize,\n fallback: [224, 224],\n }),\n options.mean ?? IMAGENET_MEAN,\n options.std ?? IMAGENET_STD,\n options.applySoftmax ?? true,\n );\n }\n\n /** Class labels indexed by class id. */\n get labels(): readonly string[] {\n return this._labels;\n }\n\n /** Class id → class name dict (matches Ultralytics' `model.names`). */\n get names(): Readonly<Record<number, string>> {\n return this._names;\n }\n\n /**\n * The `[width, height]` this task preprocesses to.\n *\n * Resolved at creation time from the model's graph when it declares a static\n * input, so reading it back tells you the resolution inference really runs at\n * — not merely what was requested.\n */\n get inputSize(): readonly [number, number] {\n return this._inputSize;\n }\n\n /** Number of classes the model can predict. */\n get numClasses(): number {\n return this._labels.length;\n }\n\n /** Alias for {@link predict} (parity with PyTorch `nn.Module.__call__`). */\n async call(\n image: ImageInput,\n options: ClassifierPredictOptions = {},\n ): Promise<ClassificationResults[]> {\n return this.predict(image, options);\n }\n\n /** Run classification on a single image. */\n async predict(\n image: ImageInput,\n options: ClassifierPredictOptions = {},\n ): Promise<ClassificationResults[]> {\n const timer = new SpeedTimer();\n const path = typeof image === \"string\" ? image : null;\n const original = await loadImage(image);\n timer.stage(\"load\");\n const tensor = this._preprocess(original);\n timer.stage(\"preprocess\");\n const outputs = await this._session.run({ [this._session.inputName]: tensor });\n this._pipeline.release();\n timer.stage(\"inference\");\n const firstOutputName = this._session.outputNames[0];\n if (firstOutputName === undefined) {\n throw new Error(\"Classifier model has no outputs.\");\n }\n const raw = outputs[firstOutputName];\n if (raw === undefined) {\n throw new Error(\n `Classifier model output ${firstOutputName} missing from run() result.`,\n );\n }\n const fullProbs = this._postprocess(raw.data as Float32Array);\n\n const { indices, values } = topK(fullProbs, options.topK ?? null);\n const probabilities: ClassProbability[] = [];\n for (let i = 0; i < indices.length; i++) {\n const id = indices[i] as number;\n const className = this._labels[id] ?? `class_${id}`;\n probabilities.push({\n classId: id,\n className,\n probability: values[i] as number,\n cls: id,\n name: className,\n conf: values[i] as number,\n });\n }\n if (probabilities.length === 0) {\n throw new Error(\"Classifier produced no probabilities (empty output).\");\n }\n\n const top = probabilities[0] as ClassProbability;\n const result: ClassificationResult = {\n classId: top.classId,\n className: top.className,\n confidence: top.probability,\n cls: top.classId,\n name: top.className,\n conf: top.probability,\n image: original,\n probabilities,\n };\n\n const orig: readonly [number, number] = [original.height, original.width];\n const probs = new Probs(fullProbs);\n timer.stage(\"postprocess\");\n return [\n new ClassificationResults(\n probs,\n result,\n this._names,\n original,\n orig,\n path,\n timer.speed(),\n ),\n ];\n }\n\n private _preprocess(image: RGBImage): ort.Tensor {\n const [tw, th] = this._inputSize;\n const { data } = this._pipeline.run(image);\n return toFloat32Tensor(data, [1, 3, th, tw]);\n }\n\n private _postprocess(raw: Float32Array): Float32Array {\n return this._applySoftmax ? softmax(raw) : new Float32Array(raw);\n }\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,IAAM,IAAmD;CAAC;CAAO;CAAO;AAAK,GACvE,IAAkD;CAAC;CAAO;CAAO;AAAK,GAqE/D,IAAb,MAAa,UAAmB,EAAW;CAGlB;CACA;CACA;CACA;CACA;CACA;CAPrB,YACI,GACA,GACA,GACA,GACA,GACA,GACA,GACF;EADmB,AAEjB,MAAM,CAAO,GAPI,KAAA,UAAA,GACA,KAAA,SAAA,GACA,KAAA,aAAA,GACA,KAAA,QAAA,GACA,KAAA,OAAA,GACA,KAAA,gBAAA;CAGrB;CAEA,iBAAgD;CAchD,MAAM,OAAO,IAAe,GAAkB;EAC1C,IAAM,CAAC,GAAI,KAAM,KAAK;EACtB,KAAK,IAAI,IAAI,GAAG,IAAI,GAAM,KAAK;GAC3B,IAAM,IAAS,EAAgB,EAAe,GAAI,CAAE,GAAG;IAAC;IAAG;IAAG;IAAI;GAAE,CAAC;GACrE,MAAM,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,YAAY,EAAO,CAAC;EACjE;CACJ;CASA,IAAY,YAA4B;EACpC,IAAI,KAAK,mBAAmB,MAAM;GAC9B,IAAM,CAAC,GAAI,KAAM,KAAK;GACtB,KAAK,iBAAiB,IAAI,EAAe,GAAI,GAAI,KAAK,OAAO,KAAK,IAAI;EAC1E;EACA,OAAO,KAAK;CAChB;CAGA,aAAa,OAAO,GAAoB,IAA6B,CAAC,GAAwB;EAC1F,IAAM,IAAU,MAAM,EAAW,OAAO,GAAO,CAAO,GAChD,IACF,EAAQ,cAAc,EAAyB,EAAQ,WAAW,KAAK,KAAA,GACrE,IAAS,EAAc,EAAQ,UAAU,EAAW,EAAQ,QAAQ,GAAG,EACzE,cACJ,CAAC,GACK,IAAgC,CAAC;EACvC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAO,QAAQ,KAC/B,EAAM,KAAK,EAAO;EAEtB,OAAO,IAAI,EACP,GACA,GACA,GACA,EAAiB;GACb,YAAY,EAAQ;GACpB,WAAW,EAAQ;GACnB,UAAU,CAAC,KAAK,GAAG;EACvB,CAAC,GACD,EAAQ,QAAQ,GAChB,EAAQ,OAAO,GACf,EAAQ,gBAAgB,EAC5B;CACJ;CAGA,IAAI,SAA4B;EAC5B,OAAO,KAAK;CAChB;CAGA,IAAI,QAA0C;EAC1C,OAAO,KAAK;CAChB;CASA,IAAI,YAAuC;EACvC,OAAO,KAAK;CAChB;CAGA,IAAI,aAAqB;EACrB,OAAO,KAAK,QAAQ;CACxB;CAGA,MAAM,KACF,GACA,IAAoC,CAAC,GACL;EAChC,OAAO,KAAK,QAAQ,GAAO,CAAO;CACtC;CAGA,MAAM,QACF,GACA,IAAoC,CAAC,GACL;EAChC,IAAM,IAAQ,IAAI,EAAW,GACvB,IAAO,OAAO,KAAU,WAAW,IAAQ,MAC3C,IAAW,MAAM,EAAU,CAAK;EACtC,EAAM,MAAM,MAAM;EAClB,IAAM,IAAS,KAAK,YAAY,CAAQ;EACxC,EAAM,MAAM,YAAY;EACxB,IAAM,IAAU,MAAM,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,YAAY,EAAO,CAAC;EAE7E,AADA,KAAK,UAAU,QAAQ,GACvB,EAAM,MAAM,WAAW;EACvB,IAAM,IAAkB,KAAK,SAAS,YAAY;EAClD,IAAI,MAAoB,KAAA,GACpB,MAAU,MAAM,kCAAkC;EAEtD,IAAM,IAAM,EAAQ;EACpB,IAAI,MAAQ,KAAA,GACR,MAAU,MACN,2BAA2B,EAAgB,4BAC/C;EAEJ,IAAM,IAAY,KAAK,aAAa,EAAI,IAAoB,GAEtD,EAAE,YAAS,cAAW,EAAK,GAAW,EAAQ,QAAQ,IAAI,GAC1D,IAAoC,CAAC;EAC3C,KAAK,IAAI,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAAK;GACrC,IAAM,IAAK,EAAQ,IACb,IAAY,KAAK,QAAQ,MAAO,SAAS;GAC/C,EAAc,KAAK;IACf,SAAS;IACT;IACA,aAAa,EAAO;IACpB,KAAK;IACL,MAAM;IACN,MAAM,EAAO;GACjB,CAAC;EACL;EACA,IAAI,EAAc,WAAW,GACzB,MAAU,MAAM,sDAAsD;EAG1E,IAAM,IAAM,EAAc,IACpB,IAA+B;GACjC,SAAS,EAAI;GACb,WAAW,EAAI;GACf,YAAY,EAAI;GAChB,KAAK,EAAI;GACT,MAAM,EAAI;GACV,MAAM,EAAI;GACV,OAAO;GACP;EACJ,GAEM,IAAkC,CAAC,EAAS,QAAQ,EAAS,KAAK,GAClE,IAAQ,IAAI,EAAM,CAAS;EAEjC,OADA,EAAM,MAAM,aAAa,GAClB,CACH,IAAI,EACA,GACA,GACA,KAAK,QACL,GACA,GACA,GACA,EAAM,MAAM,CAChB,CACJ;CACJ;CAEA,YAAoB,GAA6B;EAC7C,IAAM,CAAC,GAAI,KAAM,KAAK,YAChB,EAAE,YAAS,KAAK,UAAU,IAAI,CAAK;EACzC,OAAO,EAAgB,GAAM;GAAC;GAAG;GAAG;GAAI;EAAE,CAAC;CAC/C;CAEA,aAAqB,GAAiC;EAClD,OAAO,KAAK,gBAAgB,EAAQ,CAAG,IAAI,IAAI,aAAa,CAAG;CACnE;AACJ"}
|
|
1
|
+
{"version":3,"file":"classifier.js","names":[],"sources":["../../../src/vision/tasks/classifier.ts"],"sourcesContent":["/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */\n/**\n * Image classification task using ONNX Runtime Web.\n */\n\nimport type * as ort from \"onnxruntime-web\";\n\nimport { type ModelSource, type OrtSessionOptions, OrtSession } from \"../core/session\";\nimport { SpeedTimer } from \"../core/timing\";\nimport { type ImageInput, loadImage } from \"../io/image\";\nimport { classificationNumClasses, resolveInputSize } from \"../core/graph\";\nimport { modelNames } from \"../core/metadata\";\nimport { type LabelSpec, resolveLabels } from \"../labels\";\nimport {\n type Normalization,\n isUltralyticsClassifier,\n resolveNormalization,\n} from \"../normalization\";\nimport { softmax, topK } from \"../postprocess/classification\";\nimport { toFloat32Tensor } from \"../preprocess/image\";\nimport { ResizePipeline, zeroTensorData } from \"../preprocess/pipeline\";\nimport { ClassificationResults, Probs } from \"../results\";\nimport { VisionTask } from \"./base\";\nimport { type ClassProbability, type ClassificationResult, type RGBImage } from \"../types\";\n\nexport interface ClassifierOptions extends OrtSessionOptions {\n /**\n * Class label spec — see {@link resolveLabels}.\n *\n * Optional: when omitted, the names the export baked into the model are used\n * (Ultralytics writes them as `names` in the metadata map). Only when the\n * model carries none does this fall back to generated `class_<id>` labels.\n * Passing a spec always wins, for a model whose names are wrong or absent.\n */\n readonly labels?: LabelSpec;\n /**\n * Number of classes the model can predict.\n *\n * Optional: inferred from the classification head's declared output shape\n * `(B, nc)`. Pass it to validate that the supplied labels match the model.\n */\n readonly numClasses?: number;\n /**\n * Model input `[width, height]` in pixels.\n *\n * Only used when the model's graph leaves its spatial axes dynamic: a graph\n * that declares a static size always wins, since that is the only shape ONNX\n * Runtime will accept. Defaults to `[224, 224]`.\n */\n readonly inputSize?: readonly [number, number];\n /**\n * Which preprocessing this model expects — see {@link Normalization}.\n *\n * Defaults to `\"auto\"`, which reads the model's own export metadata and picks\n * `\"ultralytics\"` (raw `[0, 1]`) for an Ultralytics classification head and\n * `\"imagenet\"` for everything else.\n */\n readonly normalization?: Normalization;\n /** Per-channel RGB mean, overriding the preset. Defaults to the preset's. */\n readonly mean?: readonly [number, number, number];\n /** Per-channel RGB standard deviation, overriding the preset. */\n readonly std?: readonly [number, number, number];\n /**\n * Whether the model's output still needs a softmax.\n *\n * Left undefined (the default), this reads the model's metadata and answers\n * `false` for an Ultralytics classification export, whose graph already ends\n * in one — applying a second softmax to a probability vector keeps the\n * ranking but flattens the confidences, so the top-1 stays right while every\n * number attached to it is wrong. Detection covers that family; for any other\n * model that already emits probabilities, pass `false` explicitly.\n */\n readonly applySoftmax?: boolean;\n}\n\nexport interface ClassifierPredictOptions {\n /**\n * If set, the per-class probability list in `results[0].result.probabilities`\n * is truncated to the top-K entries. The bulk `probs` view always exposes\n * the full vector.\n */\n readonly topK?: number;\n}\n\n/**\n * Image classifier wrapping an ONNX model with ImageNet-style preprocessing.\n *\n * `predict()` returns `Promise<ClassificationResults[]>` (length 1 for a\n * single image), mirroring Ultralytics' API. The envelope exposes a `probs`\n * collection (`top1`, `top1conf`, `top5`, `top5conf`, `data`) plus the\n * legacy per-class probability list with names already resolved.\n *\n * Defaults: 224×224 RGB input, `float32` normalized with ImageNet mean/std,\n * NCHW layout, batch size 1, softmax applied to the raw output.\n *\n * @example\n * ```typescript\n * const clf = await Classifier.create(\"/models/resnet50.onnx\", {\n * labels: [\"tench\", \"goldfish\", ...] // 1000 ImageNet labels\n * });\n * const r = (await clf.predict(\"/images/dog.jpg\"))[0];\n * console.log(r.cls, r.conf, r.name);\n * console.log(r.probs.top5, r.probs.top5conf);\n * ```\n */\nexport class Classifier extends VisionTask {\n private constructor(\n session: OrtSession,\n private readonly _labels: readonly string[],\n private readonly _names: Readonly<Record<number, string>>,\n private readonly _inputSize: readonly [number, number],\n private readonly _mean: readonly [number, number, number],\n private readonly _std: readonly [number, number, number],\n private readonly _applySoftmax: boolean,\n private readonly _normalization: string,\n ) {\n super(session);\n }\n\n /**\n * Whether a softmax is applied to the model's output before ranking.\n *\n * Resolved once at construction. Worth reading when confidences look\n * compressed: a second softmax over an already-normalized vector leaves the\n * ordering intact and the numbers meaningless, which is invisible to any check\n * that only looks at the predicted class.\n */\n get appliesSoftmax(): boolean {\n return this._applySoftmax;\n }\n\n /**\n * Which preprocessing this classifier applies to every image.\n *\n * One of the {@link Normalization} preset names, or `\"custom\"` when the caller\n * supplied `mean`/`std` directly. Worth reading when a model underperforms:\n * feeding a classifier a differently prepared tensor than it was trained on\n * degrades it without throwing anything, so \"what does this assume\" is the\n * first question.\n */\n get normalization(): string {\n return this._normalization;\n }\n\n private _pipelineCache: ResizePipeline | null = null;\n\n /**\n * Run the model once on a zero tensor, paying one-time costs up front.\n *\n * The first inference of a session is not representative: WebGPU compiles its\n * shaders on it and the WASM backend faults in its arenas. Calling this while\n * a loading spinner is still up moves that cost somewhere the user is already\n * waiting — which matters most for a classifier running as the last step of\n * an on-device analysis, where the delay lands right before the answer shows.\n *\n * @param runs How many warm-up inferences to run. One is enough for WASM;\n * WebGPU sometimes settles on the second.\n */\n async warmup(runs: number = 1): Promise<void> {\n const [tw, th] = this._inputSize;\n for (let i = 0; i < runs; i++) {\n const tensor = toFloat32Tensor(zeroTensorData(tw, th), [1, 3, th, tw]);\n await this._session.run({ [this._session.inputName]: tensor });\n }\n }\n\n /**\n * The fused preprocessing pipeline, built on first use.\n *\n * Lazily, because constructing it reserves the output buffer: a task built in\n * an environment without a canvas implementation stays constructible, and only\n * fails if it is actually asked to preprocess something.\n */\n private get _pipeline(): ResizePipeline {\n if (this._pipelineCache === null) {\n const [tw, th] = this._inputSize;\n this._pipelineCache = new ResizePipeline(tw, th, this._mean, this._std);\n }\n return this._pipelineCache;\n }\n\n /**\n * Load the model, resolve labels, and settle the preprocessing.\n *\n * @param model The model source — a URL, or the bytes.\n * @param options Labels, input size, normalization, and session options.\n * @throws {RangeError} If `normalization` names an unknown preset, or names\n * one while `mean`/`std` are also given.\n */\n static async create(model: ModelSource, options: ClassifierOptions = {}): Promise<Classifier> {\n const session = await OrtSession.create(model, options);\n const normalization = resolveNormalization(session.metadata, {\n normalization: options.normalization,\n mean: options.mean,\n std: options.std,\n });\n const numClasses =\n options.numClasses ?? classificationNumClasses(session.outputShape) ?? undefined;\n const labels = resolveLabels(options.labels ?? modelNames(session.metadata), {\n numClasses,\n });\n const names: Record<number, string> = {};\n for (let i = 0; i < labels.length; i++) {\n names[i] = labels[i] as string;\n }\n return new Classifier(\n session,\n labels,\n names,\n resolveInputSize({\n graphShape: session.inputShape,\n requested: options.inputSize,\n fallback: [224, 224],\n }),\n normalization.mean,\n normalization.std,\n options.applySoftmax ?? !isUltralyticsClassifier(session.metadata),\n normalization.name,\n );\n }\n\n /** Class labels indexed by class id. */\n get labels(): readonly string[] {\n return this._labels;\n }\n\n /** Class id → class name dict (matches Ultralytics' `model.names`). */\n get names(): Readonly<Record<number, string>> {\n return this._names;\n }\n\n /**\n * The `[width, height]` this task preprocesses to.\n *\n * Resolved at creation time from the model's graph when it declares a static\n * input, so reading it back tells you the resolution inference really runs at\n * — not merely what was requested.\n */\n get inputSize(): readonly [number, number] {\n return this._inputSize;\n }\n\n /** Number of classes the model can predict. */\n get numClasses(): number {\n return this._labels.length;\n }\n\n /** Alias for {@link predict} (parity with PyTorch `nn.Module.__call__`). */\n async call(\n image: ImageInput,\n options: ClassifierPredictOptions = {},\n ): Promise<ClassificationResults[]> {\n return this.predict(image, options);\n }\n\n /** Run classification on a single image. */\n async predict(\n image: ImageInput,\n options: ClassifierPredictOptions = {},\n ): Promise<ClassificationResults[]> {\n const timer = new SpeedTimer();\n const path = typeof image === \"string\" ? image : null;\n const original = await loadImage(image);\n timer.stage(\"load\");\n const tensor = this._preprocess(original);\n timer.stage(\"preprocess\");\n const outputs = await this._session.run({ [this._session.inputName]: tensor });\n this._pipeline.release();\n timer.stage(\"inference\");\n const firstOutputName = this._session.outputNames[0];\n if (firstOutputName === undefined) {\n throw new Error(\"Classifier model has no outputs.\");\n }\n const raw = outputs[firstOutputName];\n if (raw === undefined) {\n throw new Error(\n `Classifier model output ${firstOutputName} missing from run() result.`,\n );\n }\n const fullProbs = this._postprocess(raw.data as Float32Array);\n\n const { indices, values } = topK(fullProbs, options.topK ?? null);\n const probabilities: ClassProbability[] = [];\n for (let i = 0; i < indices.length; i++) {\n const id = indices[i] as number;\n const className = this._labels[id] ?? `class_${id}`;\n probabilities.push({\n classId: id,\n className,\n probability: values[i] as number,\n cls: id,\n name: className,\n conf: values[i] as number,\n });\n }\n if (probabilities.length === 0) {\n throw new Error(\"Classifier produced no probabilities (empty output).\");\n }\n\n const top = probabilities[0] as ClassProbability;\n const result: ClassificationResult = {\n classId: top.classId,\n className: top.className,\n confidence: top.probability,\n cls: top.classId,\n name: top.className,\n conf: top.probability,\n image: original,\n probabilities,\n };\n\n const orig: readonly [number, number] = [original.height, original.width];\n const probs = new Probs(fullProbs);\n timer.stage(\"postprocess\");\n return [\n new ClassificationResults(\n probs,\n result,\n this._names,\n original,\n orig,\n path,\n timer.speed(),\n ),\n ];\n }\n\n private _preprocess(image: RGBImage): ort.Tensor {\n const [tw, th] = this._inputSize;\n const { data } = this._pipeline.run(image);\n return toFloat32Tensor(data, [1, 3, th, tw]);\n }\n\n private _postprocess(raw: Float32Array): Float32Array {\n return this._applySoftmax ? softmax(raw) : new Float32Array(raw);\n }\n}\n"],"mappings":"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"}
|
package/dist/vision.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./vision/use-camera-stream.cjs"),t=require("./vision/core/exceptions.cjs"),n=require("./vision/types.cjs"),r=require("./vision/core/timing.cjs"),i=require("./vision/results.cjs"),a=require("./vision/labels.cjs"),o=require("./vision/core/graph.cjs"),s=require("./vision/core/metadata.cjs"),c=require("./vision/core/providers.cjs"),l=require("./vision/core/session.cjs"),u=require("./vision/io/image.cjs"),
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./vision/use-camera-stream.cjs"),t=require("./vision/core/exceptions.cjs"),n=require("./vision/types.cjs"),r=require("./vision/core/timing.cjs"),i=require("./vision/results.cjs"),a=require("./vision/labels.cjs"),o=require("./vision/core/graph.cjs"),s=require("./vision/core/metadata.cjs"),c=require("./vision/core/providers.cjs"),l=require("./vision/core/session.cjs"),u=require("./vision/normalization.cjs"),d=require("./vision/io/image.cjs"),f=require("./vision/fusion.cjs"),p=require("./vision/preprocess/image.cjs"),m=require("./vision/preprocess/pipeline.cjs"),h=require("./vision/postprocess/classification.cjs"),g=require("./vision/postprocess/detection.cjs"),_=require("./vision/postprocess/segmentation.cjs"),v=require("./vision/tasks/base.cjs"),y=require("./vision/tasks/classifier.cjs"),b=require("./vision/tasks/detectClassify.cjs"),x=require("./vision/tasks/detector.cjs"),S=require("./vision/tasks/segmenter.cjs"),C=require("./vision/index.cjs"),w=require("./vision/luminance.cjs"),T=require("./vision/use-live-luminance.cjs");exports.BoundingBox=n.BoundingBox,exports.Boxes=i.Boxes,exports.COCO_CLASSES=a.COCO_CLASSES,exports.CUSTOM_NORMALIZATION=u.CUSTOM_NORMALIZATION,exports.ClassificationResults=i.ClassificationResults,exports.Classifier=y.Classifier,exports.DEFAULT_PROVIDERS=c.DEFAULT_PROVIDERS,exports.DetectClassify=b.DetectClassify,exports.DetectClassifyResults=i.DetectClassifyResults,exports.DetectionResults=i.DetectionResults,exports.Detector=x.Detector,exports.FUSION_KIND_DETECT_CLASSIFY=f.FUSION_KIND_DETECT_CLASSIFY,exports.FusionError=t.FusionError,exports.IDENTITY_MEAN=u.IDENTITY_MEAN,exports.IDENTITY_STD=u.IDENTITY_STD,exports.IMAGENET_MEAN=u.IMAGENET_MEAN,exports.IMAGENET_STD=u.IMAGENET_STD,exports.INPUT_IMAGE=f.INPUT_IMAGE,exports.INPUT_PAD=f.INPUT_PAD,exports.INPUT_SCALE=f.INPUT_SCALE,exports.INPUT_SOURCE=f.INPUT_SOURCE,exports.ImageLoadError=t.ImageLoadError,exports.InferenceError=t.InferenceError,exports.LUMINANCE_SAMPLE_MAX_EDGE=w.LUMINANCE_SAMPLE_MAX_EDGE,exports.LabelMapError=t.LabelMapError,exports.LetterboxPipeline=m.LetterboxPipeline,exports.LowLuminanceError=w.LowLuminanceError,exports.METADATA_PREFIX=f.METADATA_PREFIX,exports.Mask=n.Mask,exports.Masks=i.Masks,exports.ModelLoadError=t.ModelLoadError,exports.NoDetectionsError=t.NoDetectionsError,exports.OUTPUT_BOXES=f.OUTPUT_BOXES,exports.OUTPUT_CLASSES=f.OUTPUT_CLASSES,exports.OUTPUT_NUM_DETECTIONS=f.OUTPUT_NUM_DETECTIONS,exports.OUTPUT_PROBS=f.OUTPUT_PROBS,exports.OUTPUT_SCORES=f.OUTPUT_SCORES,exports.OrtSession=l.OrtSession,exports.OrtVisionError=t.OrtVisionError,exports.Probs=i.Probs,exports.ProviderNotAvailableError=t.ProviderNotAvailableError,exports.RGBImage=n.RGBImage,exports.ResizePipeline=m.ResizePipeline,exports.SegmentationResults=i.SegmentationResults,exports.Segmenter=S.Segmenter,exports.SpeedTimer=r.SpeedTimer,exports.VERSION=C.VERSION,exports.VisionTask=v.VisionTask,exports.batchedNms=g.batchedNms,exports.classificationNumClasses=o.classificationNumClasses,exports.computeImageLuminance=w.computeImageLuminance,exports.declaredShapesFrom=o.declaredShapesFrom,exports.decodeYolo=g.decodeYolo,exports.decodeYoloAnchors=g.decodeYoloAnchors,exports.decodeYoloSeg=_.decodeYoloSeg,exports.defaultLabels=a.defaultLabels,exports.detectProviders=c.detectProviders,exports.detectionNumClasses=o.detectionNumClasses,exports.fromCv2=p.fromCv2,exports.isLuminanceAcceptable=w.isLuminanceAcceptable,exports.isUltralyticsClassifier=u.isUltralyticsClassifier,exports.letterbox=p.letterbox,exports.letterboxToTensorData=m.letterboxToTensorData,exports.loadImage=d.loadImage,exports.modelNames=s.modelNames,exports.nms=g.nms,exports.normalize=p.normalize,exports.parseNames=s.parseNames,exports.readFusionSpec=f.readFusionSpec,exports.readModelMetadata=s.readModelMetadata,exports.requireDetections=v.requireDetections,exports.resize=p.resize,exports.resizeToTensorData=m.resizeToTensorData,exports.resolveInputSize=o.resolveInputSize,exports.resolveLabels=a.resolveLabels,exports.resolveNormalization=u.resolveNormalization,exports.resolveProviders=c.resolveProviders,exports.softmax=h.softmax,exports.spatialInputSize=o.spatialInputSize,exports.toCHW=p.toCHW,exports.toCv2=p.toCv2,exports.toFloat32=p.toFloat32,exports.toFloat32Tensor=p.toFloat32Tensor,exports.toTensor=p.toTensor,exports.topK=h.topK,exports.useCameraStream=e.useCameraStream,exports.useLiveLuminance=T.useLiveLuminance,exports.writePlanarFloat32=m.writePlanarFloat32,exports.zeroTensorData=m.zeroTensorData;
|
package/dist/vision.d.ts
CHANGED
|
@@ -204,7 +204,27 @@ export declare class Classifier extends VisionTask {
|
|
|
204
204
|
private readonly _mean;
|
|
205
205
|
private readonly _std;
|
|
206
206
|
private readonly _applySoftmax;
|
|
207
|
+
private readonly _normalization;
|
|
207
208
|
private constructor();
|
|
209
|
+
/**
|
|
210
|
+
* Whether a softmax is applied to the model's output before ranking.
|
|
211
|
+
*
|
|
212
|
+
* Resolved once at construction. Worth reading when confidences look
|
|
213
|
+
* compressed: a second softmax over an already-normalized vector leaves the
|
|
214
|
+
* ordering intact and the numbers meaningless, which is invisible to any check
|
|
215
|
+
* that only looks at the predicted class.
|
|
216
|
+
*/
|
|
217
|
+
get appliesSoftmax(): boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Which preprocessing this classifier applies to every image.
|
|
220
|
+
*
|
|
221
|
+
* One of the {@link Normalization} preset names, or `"custom"` when the caller
|
|
222
|
+
* supplied `mean`/`std` directly. Worth reading when a model underperforms:
|
|
223
|
+
* feeding a classifier a differently prepared tensor than it was trained on
|
|
224
|
+
* degrades it without throwing anything, so "what does this assume" is the
|
|
225
|
+
* first question.
|
|
226
|
+
*/
|
|
227
|
+
get normalization(): string;
|
|
208
228
|
private _pipelineCache;
|
|
209
229
|
/**
|
|
210
230
|
* Run the model once on a zero tensor, paying one-time costs up front.
|
|
@@ -227,7 +247,14 @@ export declare class Classifier extends VisionTask {
|
|
|
227
247
|
* fails if it is actually asked to preprocess something.
|
|
228
248
|
*/
|
|
229
249
|
private get _pipeline();
|
|
230
|
-
/**
|
|
250
|
+
/**
|
|
251
|
+
* Load the model, resolve labels, and settle the preprocessing.
|
|
252
|
+
*
|
|
253
|
+
* @param model The model source — a URL, or the bytes.
|
|
254
|
+
* @param options Labels, input size, normalization, and session options.
|
|
255
|
+
* @throws {RangeError} If `normalization` names an unknown preset, or names
|
|
256
|
+
* one while `mean`/`std` are also given.
|
|
257
|
+
*/
|
|
231
258
|
static create(model: ModelSource, options?: ClassifierOptions): Promise<Classifier>;
|
|
232
259
|
/** Class labels indexed by class id. */
|
|
233
260
|
get labels(): readonly string[];
|
|
@@ -276,14 +303,27 @@ export declare interface ClassifierOptions extends OrtSessionOptions {
|
|
|
276
303
|
* Runtime will accept. Defaults to `[224, 224]`.
|
|
277
304
|
*/
|
|
278
305
|
readonly inputSize?: readonly [number, number];
|
|
279
|
-
/**
|
|
306
|
+
/**
|
|
307
|
+
* Which preprocessing this model expects — see {@link Normalization}.
|
|
308
|
+
*
|
|
309
|
+
* Defaults to `"auto"`, which reads the model's own export metadata and picks
|
|
310
|
+
* `"ultralytics"` (raw `[0, 1]`) for an Ultralytics classification head and
|
|
311
|
+
* `"imagenet"` for everything else.
|
|
312
|
+
*/
|
|
313
|
+
readonly normalization?: Normalization;
|
|
314
|
+
/** Per-channel RGB mean, overriding the preset. Defaults to the preset's. */
|
|
280
315
|
readonly mean?: readonly [number, number, number];
|
|
281
|
-
/** Per-channel RGB standard deviation
|
|
316
|
+
/** Per-channel RGB standard deviation, overriding the preset. */
|
|
282
317
|
readonly std?: readonly [number, number, number];
|
|
283
318
|
/**
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
319
|
+
* Whether the model's output still needs a softmax.
|
|
320
|
+
*
|
|
321
|
+
* Left undefined (the default), this reads the model's metadata and answers
|
|
322
|
+
* `false` for an Ultralytics classification export, whose graph already ends
|
|
323
|
+
* in one — applying a second softmax to a probability vector keeps the
|
|
324
|
+
* ranking but flattens the confidences, so the top-1 stays right while every
|
|
325
|
+
* number attached to it is wrong. Detection covers that family; for any other
|
|
326
|
+
* model that already emits probabilities, pass `false` explicitly.
|
|
287
327
|
*/
|
|
288
328
|
readonly applySoftmax?: boolean;
|
|
289
329
|
}
|
|
@@ -369,6 +409,9 @@ export declare function computeImageLuminance(source: LuminanceSource, reusableC
|
|
|
369
409
|
*/
|
|
370
410
|
export declare type CropSource = "detector_input" | "original";
|
|
371
411
|
|
|
412
|
+
/** Name reported when the caller supplied `mean`/`std` directly. */
|
|
413
|
+
export declare const CUSTOM_NORMALIZATION = "custom";
|
|
414
|
+
|
|
372
415
|
/**
|
|
373
416
|
* One declared dimension: a number when the graph pins it, `null` when the
|
|
374
417
|
* dimension is symbolic (dynamic).
|
|
@@ -951,6 +994,29 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
951
994
|
readonly raiseOnEmpty?: boolean;
|
|
952
995
|
}
|
|
953
996
|
|
|
997
|
+
/**
|
|
998
|
+
* Narrow a provider list to the ones this browser can actually offer.
|
|
999
|
+
*
|
|
1000
|
+
* ORT-Web exposes no equivalent of Node's `session.getProviders()`, so there is
|
|
1001
|
+
* no way to ask which provider a session ended up on. What the browser *does*
|
|
1002
|
+
* answer is whether the underlying API exists at all — no `navigator.gpu`, or no
|
|
1003
|
+
* adapter behind it, means `webgpu` was never going to run — and that covers the
|
|
1004
|
+
* case that actually bites: a page asking for WebGPU on a device without it,
|
|
1005
|
+
* silently getting WASM, and being several times slower than intended with no
|
|
1006
|
+
* error to point at.
|
|
1007
|
+
*
|
|
1008
|
+
* This is best-effort by construction. A provider that survives here can still
|
|
1009
|
+
* fail inside ORT for a reason the browser does not surface (a missing shader
|
|
1010
|
+
* feature, an exhausted device), so a surviving entry means "not ruled out",
|
|
1011
|
+
* not "confirmed running". Anything this function does not know how to test is
|
|
1012
|
+
* kept rather than dropped: guessing a provider away would be worse than
|
|
1013
|
+
* admitting ignorance about it.
|
|
1014
|
+
*
|
|
1015
|
+
* @param requested Providers in preference order, already resolved.
|
|
1016
|
+
* @returns The subset that is not ruled out, in the same order.
|
|
1017
|
+
*/
|
|
1018
|
+
export declare function detectProviders(requested: readonly string[]): Promise<string[]>;
|
|
1019
|
+
|
|
954
1020
|
/**
|
|
955
1021
|
* Convert an HWC BGR uint8 buffer (OpenCV layout) to the SDK's HWC RGB.
|
|
956
1022
|
*
|
|
@@ -1039,6 +1105,12 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1039
1105
|
readonly needsSourceImage: boolean;
|
|
1040
1106
|
}
|
|
1041
1107
|
|
|
1108
|
+
/** Mean that leaves an image untouched — what an Ultralytics classifier expects. */
|
|
1109
|
+
export declare const IDENTITY_MEAN: readonly [number, number, number];
|
|
1110
|
+
|
|
1111
|
+
/** Deviation that leaves an image untouched — what an Ultralytics classifier expects. */
|
|
1112
|
+
export declare const IDENTITY_STD: readonly [number, number, number];
|
|
1113
|
+
|
|
1042
1114
|
/** Anything {@link loadImage} accepts as an image input. */
|
|
1043
1115
|
export declare type ImageInput = string | Blob | HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap | ImageData | RGBImage;
|
|
1044
1116
|
|
|
@@ -1046,6 +1118,12 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1046
1118
|
export declare class ImageLoadError extends OrtVisionError {
|
|
1047
1119
|
}
|
|
1048
1120
|
|
|
1121
|
+
/** Per-channel RGB mean of ImageNet, the torchvision preprocessing convention. */
|
|
1122
|
+
export declare const IMAGENET_MEAN: readonly [number, number, number];
|
|
1123
|
+
|
|
1124
|
+
/** Per-channel RGB standard deviation of ImageNet. */
|
|
1125
|
+
export declare const IMAGENET_STD: readonly [number, number, number];
|
|
1126
|
+
|
|
1049
1127
|
/** Raised when ONNX Runtime fails while executing a model. */
|
|
1050
1128
|
export declare class InferenceError extends OrtVisionError {
|
|
1051
1129
|
}
|
|
@@ -1076,6 +1154,17 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1076
1154
|
*/
|
|
1077
1155
|
export declare function isLuminanceAcceptable(luminance: number, threshold: number): boolean;
|
|
1078
1156
|
|
|
1157
|
+
/**
|
|
1158
|
+
* Whether a metadata map came out of `YOLO(...).export(format="onnx")`.
|
|
1159
|
+
*
|
|
1160
|
+
* Every Ultralytics export stamps `author` and `task` into its metadata, and the
|
|
1161
|
+
* pair is unambiguous: `"Ultralytics"` plus `"classify"` is a classification head
|
|
1162
|
+
* from that codebase and nothing else.
|
|
1163
|
+
*
|
|
1164
|
+
* @param metadata The model's custom metadata map.
|
|
1165
|
+
*/
|
|
1166
|
+
export declare function isUltralyticsClassifier(metadata: Readonly<Record<string, string>>): boolean;
|
|
1167
|
+
|
|
1079
1168
|
/** Raised when class labels cannot be resolved from the supplied spec. */
|
|
1080
1169
|
export declare class LabelMapError extends OrtVisionError {
|
|
1081
1170
|
}
|
|
@@ -1348,6 +1437,39 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1348
1437
|
export declare class NoDetectionsError extends OrtVisionError {
|
|
1349
1438
|
}
|
|
1350
1439
|
|
|
1440
|
+
/** @generated Vendored from @mauriciobenjamin700/ort-vision-sdk-web. Do not hand-edit — regenerate with `npm run vendor:vision`. */
|
|
1441
|
+
/**
|
|
1442
|
+
* Which preprocessing a classifier expects its input to have had.
|
|
1443
|
+
*
|
|
1444
|
+
* A classifier is trained on a specific tensor, and feeding it a differently
|
|
1445
|
+
* prepared one degrades it silently — no exception, no warning, just worse
|
|
1446
|
+
* predictions. The two families this SDK sees most disagree completely:
|
|
1447
|
+
* torchvision-style models want the ImageNet mean and deviation subtracted and
|
|
1448
|
+
* divided out, while an Ultralytics classification head consumes raw `[0, 1]`.
|
|
1449
|
+
*
|
|
1450
|
+
* Guessing wrong is not detectable from the outside, but it is not a guess: an
|
|
1451
|
+
* Ultralytics export stamps `author` and `task` into its own metadata, and every
|
|
1452
|
+
* task in this SDK already reads that map for the class names.
|
|
1453
|
+
*
|
|
1454
|
+
* Mirrors `ort_vision_sdk.normalization` in the Python SDK; the two must agree,
|
|
1455
|
+
* because the same model file is driven by both.
|
|
1456
|
+
*/
|
|
1457
|
+
/**
|
|
1458
|
+
* Which preprocessing the classifier expects its input to have had.
|
|
1459
|
+
*
|
|
1460
|
+
* - `"auto"` (the default wherever it is accepted) reads the model's own export
|
|
1461
|
+
* metadata and picks. An Ultralytics classification head gets
|
|
1462
|
+
* `"ultralytics"`; anything else gets `"imagenet"`.
|
|
1463
|
+
* - `"imagenet"` subtracts the ImageNet mean and divides by the ImageNet
|
|
1464
|
+
* deviation — the torchvision convention.
|
|
1465
|
+
* - `"ultralytics"` leaves the image in `[0, 1]`. Ultralytics' own classifier
|
|
1466
|
+
* applies no mean/std at all, so anything else feeds it images it never saw
|
|
1467
|
+
* in training.
|
|
1468
|
+
* - `"none"` is the same arithmetic as `"ultralytics"` — identity — under a
|
|
1469
|
+
* name that says "this model wants raw `[0, 1]`" rather than naming a vendor.
|
|
1470
|
+
*/
|
|
1471
|
+
export declare type Normalization = "auto" | "imagenet" | "ultralytics" | "none";
|
|
1472
|
+
|
|
1351
1473
|
/**
|
|
1352
1474
|
* Convert a uint8 image to a normalized float32 array (HWC layout preserved).
|
|
1353
1475
|
*
|
|
@@ -1364,8 +1486,32 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1364
1486
|
*/
|
|
1365
1487
|
export declare class OrtSession {
|
|
1366
1488
|
private readonly _session;
|
|
1489
|
+
/**
|
|
1490
|
+
* Execution providers this session is expected to run on.
|
|
1491
|
+
*
|
|
1492
|
+
* The requested list narrowed to what this browser can actually offer — a
|
|
1493
|
+
* `webgpu` entry survives only where an adapter exists. Best-effort: ORT-Web
|
|
1494
|
+
* exposes no way to ask which provider a session ended up on, so an entry
|
|
1495
|
+
* here means "not ruled out", not "confirmed". See
|
|
1496
|
+
* {@link requestedProviders} for what was asked for.
|
|
1497
|
+
*
|
|
1498
|
+
* When nothing survives — a caller asking for `webgpu` alone on a device
|
|
1499
|
+
* without it — this falls back to {@link FALLBACK_PROVIDER}, which ORT-Web
|
|
1500
|
+
* can always run. Handing ORT the unsatisfiable list instead makes
|
|
1501
|
+
* `InferenceSession.create` reject with "no available backend found", so the
|
|
1502
|
+
* page gets no inference at all rather than the slow-but-working fallback
|
|
1503
|
+
* the `console.warn` describes. Measured in a real Chromium, where
|
|
1504
|
+
* `navigator.gpu` exists but yields no adapter.
|
|
1505
|
+
*/
|
|
1367
1506
|
readonly providers: readonly string[];
|
|
1368
1507
|
private readonly _metadata;
|
|
1508
|
+
/**
|
|
1509
|
+
* Execution providers that were asked for, after defaults were applied.
|
|
1510
|
+
*
|
|
1511
|
+
* Kept separate because ORT-Web falls back silently: a page that asks for
|
|
1512
|
+
* `webgpu` on a device without it runs on WASM and is told nothing.
|
|
1513
|
+
*/
|
|
1514
|
+
readonly requestedProviders: readonly string[];
|
|
1369
1515
|
private constructor();
|
|
1370
1516
|
/**
|
|
1371
1517
|
* Load an ONNX model into an ORT inference session.
|
|
@@ -1449,7 +1595,12 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1449
1595
|
}
|
|
1450
1596
|
|
|
1451
1597
|
export declare interface OrtSessionOptions {
|
|
1452
|
-
/**
|
|
1598
|
+
/**
|
|
1599
|
+
* Execution providers in preference order. `undefined` uses {@link DEFAULT_PROVIDERS}.
|
|
1600
|
+
*
|
|
1601
|
+
* Naming one explicitly also opts into a `console.warn` when this browser
|
|
1602
|
+
* cannot offer it, instead of falling back in silence.
|
|
1603
|
+
*/
|
|
1453
1604
|
readonly providers?: readonly string[];
|
|
1454
1605
|
/** Optional ORT session options forwarded to `InferenceSession.create`. */
|
|
1455
1606
|
readonly sessionOptions?: ort.InferenceSession.SessionOptions;
|
|
@@ -1484,7 +1635,14 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1484
1635
|
constructor(message: string, options?: ErrorOptions);
|
|
1485
1636
|
}
|
|
1486
1637
|
|
|
1487
|
-
/**
|
|
1638
|
+
/**
|
|
1639
|
+
* Name of the `[K, 4]` float32 xyxy output, in **letterboxed** input pixels.
|
|
1640
|
+
*
|
|
1641
|
+
* A file fused by `ort-vision-sdk` 0.9.0 or later reports the box that was
|
|
1642
|
+
* actually classified: clamped to the image the crop came from, exactly as
|
|
1643
|
+
* RoiAlign received it. Older files report the raw box, so one that ran off the
|
|
1644
|
+
* frame draws a rectangle wider than the region the classifier saw.
|
|
1645
|
+
*/
|
|
1488
1646
|
export declare const OUTPUT_BOXES = "boxes";
|
|
1489
1647
|
|
|
1490
1648
|
/** Name of the `[K]` int64 detector-class output. */
|
|
@@ -1529,9 +1687,20 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1529
1687
|
get top1(): number;
|
|
1530
1688
|
/** Probability of the top-1 class. */
|
|
1531
1689
|
get top1conf(): number;
|
|
1532
|
-
/**
|
|
1690
|
+
/**
|
|
1691
|
+
* Indices of the top-5 most probable classes, descending.
|
|
1692
|
+
*
|
|
1693
|
+
* The array is the memoised selection itself, not a copy — reading it twice
|
|
1694
|
+
* hands back the same object. Treat it as read-only: writing into it edits
|
|
1695
|
+
* what every later read of this `Probs` returns.
|
|
1696
|
+
*/
|
|
1533
1697
|
get top5(): Int32Array;
|
|
1534
|
-
/**
|
|
1698
|
+
/**
|
|
1699
|
+
* Probabilities of the top-5 classes, descending.
|
|
1700
|
+
*
|
|
1701
|
+
* Shares the memoised selection with {@link Probs.top5}, under the same
|
|
1702
|
+
* read-only caveat.
|
|
1703
|
+
*/
|
|
1535
1704
|
get top5conf(): Float32Array;
|
|
1536
1705
|
private _cache;
|
|
1537
1706
|
/**
|
|
@@ -1552,12 +1721,14 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1552
1721
|
* A full sort to read five entries out of a thousand-class vector costs
|
|
1553
1722
|
* O(n log n) plus an index array the size of the vector; keeping `k` slots
|
|
1554
1723
|
* ordered by insertion and scanning once costs O(n·k) with no allocation
|
|
1555
|
-
* beyond the result. Measured on 1000 classes
|
|
1556
|
-
* 1.
|
|
1724
|
+
* beyond the result. Measured on 1000 classes over 2000 iterations, 134.5 µs
|
|
1725
|
+
* against 1.5 µs for the same output.
|
|
1557
1726
|
*
|
|
1558
1727
|
* Ties keep the lower class index first, matching the stable sort this
|
|
1559
1728
|
* replaced: a candidate only displaces an entry it is strictly greater
|
|
1560
|
-
* than.
|
|
1729
|
+
* than. That is also what keeps this selection in step with the Python
|
|
1730
|
+
* SDK's `np.argsort(-data, kind="stable")`, where the sort is C and the
|
|
1731
|
+
* cost this avoids does not arise.
|
|
1561
1732
|
*
|
|
1562
1733
|
* @param k - How many classes to select.
|
|
1563
1734
|
* @returns Indices and probabilities, descending by probability.
|
|
@@ -1722,6 +1893,16 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1722
1893
|
*/
|
|
1723
1894
|
export declare function resizeToTensorData(image: RGBImage, targetWidth: number, targetHeight: number, mean?: readonly [number, number, number], std?: readonly [number, number, number]): FusedResizeResult;
|
|
1724
1895
|
|
|
1896
|
+
/** What {@link resolveNormalization} settled on. */
|
|
1897
|
+
export declare interface ResolvedNormalization {
|
|
1898
|
+
/** The preset name, or `"custom"` when the caller supplied the values. */
|
|
1899
|
+
readonly name: string;
|
|
1900
|
+
/** Per-channel mean to subtract. */
|
|
1901
|
+
readonly mean: readonly [number, number, number];
|
|
1902
|
+
/** Per-channel deviation to divide by. */
|
|
1903
|
+
readonly std: readonly [number, number, number];
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1725
1906
|
/**
|
|
1726
1907
|
* Decide the input size a task will preprocess to.
|
|
1727
1908
|
*
|
|
@@ -1757,6 +1938,30 @@ export declare const DEFAULT_PROVIDERS: readonly string[];
|
|
|
1757
1938
|
readonly numClasses?: number;
|
|
1758
1939
|
}
|
|
1759
1940
|
|
|
1941
|
+
/**
|
|
1942
|
+
* Settle which `mean`/`std` to apply, and what to call the choice.
|
|
1943
|
+
*
|
|
1944
|
+
* Explicit `mean`/`std` always win — they are the escape hatch for a model whose
|
|
1945
|
+
* preprocessing neither preset describes. Anything they leave open falls back to
|
|
1946
|
+
* the preset, so passing only a `mean` does not silently reset the deviation
|
|
1947
|
+
* to 1.
|
|
1948
|
+
*
|
|
1949
|
+
* Warns (via `console.warn`) when the model is an Ultralytics export and the
|
|
1950
|
+
* supplied values are not the identity it was trained with. Nothing fails in
|
|
1951
|
+
* that case: the prediction has the right shape and is simply less accurate,
|
|
1952
|
+
* which is exactly why it is worth saying out loud.
|
|
1953
|
+
*
|
|
1954
|
+
* @param metadata The model's custom metadata map, read to detect the family.
|
|
1955
|
+
* @param options The preset asked for, plus any explicit `mean`/`std`.
|
|
1956
|
+
* @throws {RangeError} If `normalization` is not a known preset, or names one
|
|
1957
|
+
* while `mean`/`std` are also supplied — two answers to the same question.
|
|
1958
|
+
*/
|
|
1959
|
+
export declare function resolveNormalization(metadata: Readonly<Record<string, string>>, options?: {
|
|
1960
|
+
readonly normalization?: Normalization;
|
|
1961
|
+
readonly mean?: readonly [number, number, number];
|
|
1962
|
+
readonly std?: readonly [number, number, number];
|
|
1963
|
+
}): ResolvedNormalization;
|
|
1964
|
+
|
|
1760
1965
|
/**
|
|
1761
1966
|
* Resolve the execution providers to pass to `InferenceSession.create`.
|
|
1762
1967
|
*
|
package/dist/vision.js
CHANGED
|
@@ -6,21 +6,22 @@ import { Boxes as p, ClassificationResults as m, DetectClassifyResults as h, Det
|
|
|
6
6
|
import { COCO_CLASSES as b, defaultLabels as x, resolveLabels as S } from "./vision/labels.js";
|
|
7
7
|
import { classificationNumClasses as C, declaredShapesFrom as w, detectionNumClasses as T, resolveInputSize as E, spatialInputSize as D } from "./vision/core/graph.js";
|
|
8
8
|
import { modelNames as O, parseNames as k, readModelMetadata as A } from "./vision/core/metadata.js";
|
|
9
|
-
import { DEFAULT_PROVIDERS as j,
|
|
10
|
-
import { OrtSession as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
|
|
9
|
+
import { DEFAULT_PROVIDERS as j, detectProviders as M, resolveProviders as N } from "./vision/core/providers.js";
|
|
10
|
+
import { OrtSession as P } from "./vision/core/session.js";
|
|
11
|
+
import { CUSTOM_NORMALIZATION as F, IDENTITY_MEAN as I, IDENTITY_STD as L, IMAGENET_MEAN as R, IMAGENET_STD as z, isUltralyticsClassifier as B, resolveNormalization as V } from "./vision/normalization.js";
|
|
12
|
+
import { loadImage as H } from "./vision/io/image.js";
|
|
13
|
+
import { FUSION_KIND_DETECT_CLASSIFY as U, INPUT_IMAGE as W, INPUT_PAD as G, INPUT_SCALE as K, INPUT_SOURCE as q, METADATA_PREFIX as J, OUTPUT_BOXES as Y, OUTPUT_CLASSES as X, OUTPUT_NUM_DETECTIONS as Z, OUTPUT_PROBS as Q, OUTPUT_SCORES as $, readFusionSpec as ee } from "./vision/fusion.js";
|
|
14
|
+
import { fromCv2 as te, letterbox as ne, normalize as re, resize as ie, toCHW as ae, toCv2 as oe, toFloat32 as se, toFloat32Tensor as ce, toTensor as le } from "./vision/preprocess/image.js";
|
|
15
|
+
import { LetterboxPipeline as ue, ResizePipeline as de, letterboxToTensorData as fe, resizeToTensorData as pe, writePlanarFloat32 as me, zeroTensorData as he } from "./vision/preprocess/pipeline.js";
|
|
16
|
+
import { softmax as ge, topK as _e } from "./vision/postprocess/classification.js";
|
|
17
|
+
import { batchedNms as ve, decodeYolo as ye, decodeYoloAnchors as be, nms as xe } from "./vision/postprocess/detection.js";
|
|
18
|
+
import { decodeYoloSeg as Se } from "./vision/postprocess/segmentation.js";
|
|
19
|
+
import { VisionTask as Ce, requireDetections as we } from "./vision/tasks/base.js";
|
|
20
|
+
import { Classifier as Te } from "./vision/tasks/classifier.js";
|
|
21
|
+
import { DetectClassify as Ee } from "./vision/tasks/detectClassify.js";
|
|
22
|
+
import { Detector as De } from "./vision/tasks/detector.js";
|
|
23
|
+
import { Segmenter as Oe } from "./vision/tasks/segmenter.js";
|
|
24
|
+
import { VERSION as ke } from "./vision/index.js";
|
|
25
|
+
import { LUMINANCE_SAMPLE_MAX_EDGE as Ae, LowLuminanceError as je, computeImageLuminance as Me, isLuminanceAcceptable as Ne } from "./vision/luminance.js";
|
|
26
|
+
import { useLiveLuminance as Pe } from "./vision/use-live-luminance.js";
|
|
27
|
+
export { l as BoundingBox, p as Boxes, b as COCO_CLASSES, F as CUSTOM_NORMALIZATION, m as ClassificationResults, Te as Classifier, j as DEFAULT_PROVIDERS, Ee as DetectClassify, h as DetectClassifyResults, g as DetectionResults, De as Detector, U as FUSION_KIND_DETECT_CLASSIFY, t as FusionError, I as IDENTITY_MEAN, L as IDENTITY_STD, R as IMAGENET_MEAN, z as IMAGENET_STD, W as INPUT_IMAGE, G as INPUT_PAD, K as INPUT_SCALE, q as INPUT_SOURCE, n as ImageLoadError, r as InferenceError, Ae as LUMINANCE_SAMPLE_MAX_EDGE, i as LabelMapError, ue as LetterboxPipeline, je as LowLuminanceError, J as METADATA_PREFIX, u as Mask, _ as Masks, a as ModelLoadError, o as NoDetectionsError, Y as OUTPUT_BOXES, X as OUTPUT_CLASSES, Z as OUTPUT_NUM_DETECTIONS, Q as OUTPUT_PROBS, $ as OUTPUT_SCORES, P as OrtSession, s as OrtVisionError, v as Probs, c as ProviderNotAvailableError, d as RGBImage, de as ResizePipeline, y as SegmentationResults, Oe as Segmenter, f as SpeedTimer, ke as VERSION, Ce as VisionTask, ve as batchedNms, C as classificationNumClasses, Me as computeImageLuminance, w as declaredShapesFrom, ye as decodeYolo, be as decodeYoloAnchors, Se as decodeYoloSeg, x as defaultLabels, M as detectProviders, T as detectionNumClasses, te as fromCv2, Ne as isLuminanceAcceptable, B as isUltralyticsClassifier, ne as letterbox, fe as letterboxToTensorData, H as loadImage, O as modelNames, xe as nms, re as normalize, k as parseNames, ee as readFusionSpec, A as readModelMetadata, we as requireDetections, ie as resize, pe as resizeToTensorData, E as resolveInputSize, S as resolveLabels, V as resolveNormalization, N as resolveProviders, ge as softmax, D as spatialInputSize, ae as toCHW, oe as toCv2, se as toFloat32, ce as toFloat32Tensor, le as toTensor, _e as topK, e as useCameraStream, Pe as useLiveLuminance, me as writePlanarFloat32, he as zeroTensorData };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const e=require("./base-url.cjs");function t(t,n){return`${e.basePrefix(t)}${n}`.replace(/([^:]\/)\/+/g,`$1`)}function n(t,n){let r=e.basePrefix(t);return r===`/`?n.startsWith(`/`)?n:`/${n}`:n.startsWith(r)?n:`${r}${n.replace(/^\//,``)}`}function r(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)>>>0;return t.toString(16)}function i(e={}){let{fileName:i=`precache-manifest.json`,additionalUrls:a=[],exclude:o=/\.map$/,includeHtml:s=!0,appShell:c=`/index.html`}=e,l=`/`;return{name:`tempest-pwa-manifest`,apply:`build`,configResolved(e){l=e.base??`/`},generateBundle(e,u){let d=new Set(a.map(e=>n(l,e)));c&&d.add(n(l,c));for(let e of Object.keys(u))e!==i&&(o.test(e)||!
|
|
1
|
+
const e=require("./base-url.cjs");function t(t,n){return`${e.basePrefix(t)}${n}`.replace(/([^:]\/)\/+/g,`$1`)}function n(t,n){let r=e.basePrefix(t);return r===`/`?n.startsWith(`/`)?n:`/${n}`:n.startsWith(r)?n:`${r}${n.replace(/^\//,``)}`}function r(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)>>>0;return t.toString(16)}function i(e={}){let{fileName:i=`precache-manifest.json`,additionalUrls:a=[],exclude:o=/\.map$/,includeHtml:s=!0,appShell:c=`/index.html`}=e,l=`/`;return{name:`tempest-pwa-manifest`,apply:`build`,configResolved(e){l=e.base??`/`},generateBundle(e,u){let d=new Set(a.map(e=>n(l,e)));c&&d.add(n(l,c));for(let e of Object.keys(u))e!==i&&(o.test(e)||(s||!e.endsWith(`.html`))&&d.add(t(l,e)));let f=[...d].sort(),p=r(f.join(`
|
|
2
2
|
`));this.emitFile({type:`asset`,fileName:i,source:JSON.stringify({version:p,urls:f})})}}}exports.tempestPwaManifest=i;
|
|
3
3
|
//# sourceMappingURL=tempest-pwa-manifest.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tempest-pwa-manifest.cjs","names":[],"sources":["../../src/vite/tempest-pwa-manifest.ts"],"sourcesContent":["import type { Plugin } from \"vite\";\nimport { basePrefix } from \"./base-url\";\n\n/**\n * A Vite plugin object. Typed loosely so the SDK's published declarations stay\n * free of `vite`'s internal types (which the `.d.ts` rollup can't analyze);\n * assign the result straight into a `plugins: [...]` array.\n */\nexport type TempestVitePlugin = { name: string } & Record<string, unknown>;\n\n/** Options for {@link tempestPwaManifest}. */\nexport interface TempestPwaManifestOptions {\n /** Output file name (under the build root). Default `precache-manifest.json`. */\n fileName?: string;\n /**\n * Extra URLs to precache that Vite doesn't emit into the bundle — typically\n * `public/` assets like the web manifest and icons. Default `[]`.\n *\n * Write these relative to the site root (`/icon.svg`); the resolved Vite\n * `base` is prefixed for you. An entry that already carries the base is\n * left alone, so spelling it out by hand is still correct.\n */\n additionalUrls?: string[];\n /** Emitted files matching this are skipped. Default `/\\.map$/` (source maps). */\n exclude?: RegExp;\n /** Include emitted `.html` documents (the app shell). Default `true`. */\n includeHtml?: boolean;\n /**\n * App-shell document always added to the manifest, even if Vite emits it\n * after this plugin runs. Must match `installPrecache`'s `navigateFallback`\n * so offline navigations resolve. Pass `false` to disable. Default `/index.html`.\n *\n * Like {@link TempestPwaManifestOptions.additionalUrls}, this is prefixed\n * with the resolved Vite `base`.\n */\n appShell?: string | false;\n}\n\nfunction joinBase(base: string, file: string): string {\n return `${basePrefix(base)}${file}`.replace(/([^:]\\/)\\/+/g, \"$1\");\n}\n\n/**\n * Prefix a caller-supplied, root-absolute URL with the resolved Vite `base`.\n *\n * Idempotent: a URL that already starts with the base is returned untouched,\n * so configs written before this was applied — spelling the base out by hand —\n * keep producing the same manifest instead of gaining a doubled prefix.\n */\nfunction withBase(base: string, url: string): string {\n const prefix = basePrefix(base);\n if (prefix === \"/\") return url.startsWith(\"/\") ? url : `/${url}`;\n if (url.startsWith(prefix)) return url;\n return `${prefix}${url.replace(/^\\//, \"\")}`;\n}\n\n/** Deterministic djb2 hash → hex. Stable across rebuilds with the same assets. */\nfunction hash(input: string): string {\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) >>> 0;\n }\n return h.toString(16);\n}\n\n/**\n * Vite build plugin that emits a `precache-manifest.json` listing every built\n * asset (plus any `additionalUrls`) as root-absolute URLs, with a content-based\n * `version`. It is the dependency-free counterpart to Workbox's `__WB_MANIFEST`:\n * `installPrecache` (from `tempest-react-sdk/sw`) reads this file at the service\n * worker's `install` event to cache the app shell for offline use.\n *\n * @example\n * // vite.config.ts\n * import { createViteConfig, tempestPwaManifest } from \"tempest-react-sdk/vite\";\n *\n * export default createViteConfig({\n * plugins: [tempestPwaManifest({ additionalUrls: [\"/manifest.webmanifest\", \"/icon.svg\"] })],\n * });\n */\nexport function tempestPwaManifest(options: TempestPwaManifestOptions = {}): TempestVitePlugin {\n const {\n fileName = \"precache-manifest.json\",\n additionalUrls = [],\n exclude = /\\.map$/,\n includeHtml = true,\n appShell = \"/index.html\",\n } = options;\n\n let base = \"/\";\n\n const plugin: Plugin = {\n name: \"tempest-pwa-manifest\",\n apply: \"build\",\n configResolved(config) {\n base = config.base ?? \"/\";\n },\n generateBundle(_outputOptions, bundle) {\n const urls = new Set<string>(additionalUrls.map((url) => withBase(base, url)));\n // Vite may emit index.html after this hook, so guarantee the shell.\n if (appShell) urls.add(withBase(base, appShell));\n for (const file of Object.keys(bundle)) {\n if (file === fileName) continue;\n if (exclude.test(file)) continue;\n if (!includeHtml && file.endsWith(\".html\")) continue;\n urls.add(joinBase(base, file));\n }\n\n const list = [...urls].sort();\n const version = hash(list.join(\"\\n\"));\n this.emitFile({\n type: \"asset\",\n fileName,\n source: JSON.stringify({ version, urls: list }),\n });\n },\n };\n\n return plugin as TempestVitePlugin;\n}\n"],"mappings":"kCAsCA,SAAS,EAAS,EAAc,EAAsB,CAClD,MAAO,GAAG,EAAA,WAAW,CAAI,IAAI,IAAO,QAAQ,eAAgB,IAAI,CACpE,CASA,SAAS,EAAS,EAAc,EAAqB,CACjD,IAAM,EAAS,EAAA,WAAW,CAAI,EAG9B,OAFI,IAAW,IAAY,EAAI,WAAW,GAAG,EAAI,EAAM,IAAI,IACvD,EAAI,WAAW,CAAM,EAAU,EAC5B,GAAG,IAAS,EAAI,QAAQ,MAAO,EAAE,GAC5C,CAGA,SAAS,EAAK,EAAuB,CACjC,IAAI,EAAI,KACR,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAC9B,GAAM,GAAK,GAAK,EAAI,EAAM,WAAW,CAAC,IAAO,EAEjD,OAAO,EAAE,SAAS,EAAE,CACxB,CAiBA,SAAgB,EAAmB,EAAqC,CAAC,EAAsB,CAC3F,GAAM,CACF,WAAW,yBACX,iBAAiB,CAAC,EAClB,UAAU,SACV,cAAc,GACd,WAAW,eACX,EAEA,EAAO,IA6BX,MAAO,CA1BH,KAAM,uBACN,MAAO,QACP,eAAe,EAAQ,CACnB,EAAO,EAAO,MAAQ,GAC1B,EACA,eAAe,EAAgB,EAAQ,CACnC,IAAM,EAAO,IAAI,IAAY,EAAe,IAAK,GAAQ,EAAS,EAAM,CAAG,CAAC,CAAC,EAEzE,GAAU,EAAK,IAAI,EAAS,EAAM,CAAQ,CAAC,EAC/C,IAAK,IAAM,KAAQ,OAAO,KAAK,CAAM,EAC7B,IAAS,IACT,EAAQ,KAAK,CAAI,
|
|
1
|
+
{"version":3,"file":"tempest-pwa-manifest.cjs","names":[],"sources":["../../src/vite/tempest-pwa-manifest.ts"],"sourcesContent":["import type { Plugin } from \"vite\";\nimport { basePrefix } from \"./base-url\";\n\n/**\n * A Vite plugin object. Typed loosely so the SDK's published declarations stay\n * free of `vite`'s internal types (which the `.d.ts` rollup can't analyze);\n * assign the result straight into a `plugins: [...]` array.\n */\nexport type TempestVitePlugin = { name: string } & Record<string, unknown>;\n\n/** Options for {@link tempestPwaManifest}. */\nexport interface TempestPwaManifestOptions {\n /** Output file name (under the build root). Default `precache-manifest.json`. */\n fileName?: string;\n /**\n * Extra URLs to precache that Vite doesn't emit into the bundle — typically\n * `public/` assets like the web manifest and icons. Default `[]`.\n *\n * Write these relative to the site root (`/icon.svg`); the resolved Vite\n * `base` is prefixed for you. An entry that already carries the base is\n * left alone, so spelling it out by hand is still correct.\n */\n additionalUrls?: string[];\n /** Emitted files matching this are skipped. Default `/\\.map$/` (source maps). */\n exclude?: RegExp;\n /** Include emitted `.html` documents (the app shell). Default `true`. */\n includeHtml?: boolean;\n /**\n * App-shell document always added to the manifest, even if Vite emits it\n * after this plugin runs. Must match `installPrecache`'s `navigateFallback`\n * so offline navigations resolve. Pass `false` to disable. Default `/index.html`.\n *\n * Like {@link TempestPwaManifestOptions.additionalUrls}, this is prefixed\n * with the resolved Vite `base`.\n */\n appShell?: string | false;\n}\n\nfunction joinBase(base: string, file: string): string {\n return `${basePrefix(base)}${file}`.replace(/([^:]\\/)\\/+/g, \"$1\");\n}\n\n/**\n * Prefix a caller-supplied, root-absolute URL with the resolved Vite `base`.\n *\n * Idempotent: a URL that already starts with the base is returned untouched,\n * so configs written before this was applied — spelling the base out by hand —\n * keep producing the same manifest instead of gaining a doubled prefix.\n */\nfunction withBase(base: string, url: string): string {\n const prefix = basePrefix(base);\n if (prefix === \"/\") return url.startsWith(\"/\") ? url : `/${url}`;\n if (url.startsWith(prefix)) return url;\n return `${prefix}${url.replace(/^\\//, \"\")}`;\n}\n\n/** Deterministic djb2 hash → hex. Stable across rebuilds with the same assets. */\nfunction hash(input: string): string {\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) >>> 0;\n }\n return h.toString(16);\n}\n\n/**\n * Vite build plugin that emits a `precache-manifest.json` listing every built\n * asset (plus any `additionalUrls`) as root-absolute URLs, with a content-based\n * `version`. It is the dependency-free counterpart to Workbox's `__WB_MANIFEST`:\n * `installPrecache` (from `tempest-react-sdk/sw`) reads this file at the service\n * worker's `install` event to cache the app shell for offline use.\n *\n * @example\n * // vite.config.ts\n * import { createViteConfig, tempestPwaManifest } from \"tempest-react-sdk/vite\";\n *\n * export default createViteConfig({\n * plugins: [tempestPwaManifest({ additionalUrls: [\"/manifest.webmanifest\", \"/icon.svg\"] })],\n * });\n */\nexport function tempestPwaManifest(options: TempestPwaManifestOptions = {}): TempestVitePlugin {\n const {\n fileName = \"precache-manifest.json\",\n additionalUrls = [],\n exclude = /\\.map$/,\n includeHtml = true,\n appShell = \"/index.html\",\n } = options;\n\n let base = \"/\";\n\n const plugin: Plugin = {\n name: \"tempest-pwa-manifest\",\n apply: \"build\",\n configResolved(config) {\n base = config.base ?? \"/\";\n },\n generateBundle(_outputOptions, bundle) {\n const urls = new Set<string>(additionalUrls.map((url) => withBase(base, url)));\n // Vite may emit index.html after this hook, so guarantee the shell.\n if (appShell) urls.add(withBase(base, appShell));\n for (const file of Object.keys(bundle)) {\n if (file === fileName) continue;\n if (exclude.test(file)) continue;\n if (!includeHtml && file.endsWith(\".html\")) continue;\n urls.add(joinBase(base, file));\n }\n\n const list = [...urls].sort();\n const version = hash(list.join(\"\\n\"));\n this.emitFile({\n type: \"asset\",\n fileName,\n source: JSON.stringify({ version, urls: list }),\n });\n },\n };\n\n return plugin as TempestVitePlugin;\n}\n"],"mappings":"kCAsCA,SAAS,EAAS,EAAc,EAAsB,CAClD,MAAO,GAAG,EAAA,WAAW,CAAI,IAAI,IAAO,QAAQ,eAAgB,IAAI,CACpE,CASA,SAAS,EAAS,EAAc,EAAqB,CACjD,IAAM,EAAS,EAAA,WAAW,CAAI,EAG9B,OAFI,IAAW,IAAY,EAAI,WAAW,GAAG,EAAI,EAAM,IAAI,IACvD,EAAI,WAAW,CAAM,EAAU,EAC5B,GAAG,IAAS,EAAI,QAAQ,MAAO,EAAE,GAC5C,CAGA,SAAS,EAAK,EAAuB,CACjC,IAAI,EAAI,KACR,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAC9B,GAAM,GAAK,GAAK,EAAI,EAAM,WAAW,CAAC,IAAO,EAEjD,OAAO,EAAE,SAAS,EAAE,CACxB,CAiBA,SAAgB,EAAmB,EAAqC,CAAC,EAAsB,CAC3F,GAAM,CACF,WAAW,yBACX,iBAAiB,CAAC,EAClB,UAAU,SACV,cAAc,GACd,WAAW,eACX,EAEA,EAAO,IA6BX,MAAO,CA1BH,KAAM,uBACN,MAAO,QACP,eAAe,EAAQ,CACnB,EAAO,EAAO,MAAQ,GAC1B,EACA,eAAe,EAAgB,EAAQ,CACnC,IAAM,EAAO,IAAI,IAAY,EAAe,IAAK,GAAQ,EAAS,EAAM,CAAG,CAAC,CAAC,EAEzE,GAAU,EAAK,IAAI,EAAS,EAAM,CAAQ,CAAC,EAC/C,IAAK,IAAM,KAAQ,OAAO,KAAK,CAAM,EAC7B,IAAS,IACT,EAAQ,KAAK,CAAI,IAChB,GAAe,GAAK,SAAS,OAAO,IACzC,EAAK,IAAI,EAAS,EAAM,CAAI,CAAC,GAGjC,IAAM,EAAO,CAAC,GAAG,CAAI,CAAC,CAAC,KAAK,EACtB,EAAU,EAAK,EAAK,KAAK;CAAI,CAAC,EACpC,KAAK,SAAS,CACV,KAAM,QACN,WACA,OAAQ,KAAK,UAAU,CAAE,UAAS,KAAM,CAAK,CAAC,CAClD,CAAC,CACL,CAGG,CACX"}
|
|
@@ -23,7 +23,7 @@ function i(e = {}) {
|
|
|
23
23
|
generateBundle(e, u) {
|
|
24
24
|
let d = new Set(a.map((e) => n(l, e)));
|
|
25
25
|
c && d.add(n(l, c));
|
|
26
|
-
for (let e of Object.keys(u)) e !== i && (o.test(e) ||
|
|
26
|
+
for (let e of Object.keys(u)) e !== i && (o.test(e) || (s || !e.endsWith(".html")) && d.add(t(l, e)));
|
|
27
27
|
let f = [...d].sort(), p = r(f.join("\n"));
|
|
28
28
|
this.emitFile({
|
|
29
29
|
type: "asset",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tempest-pwa-manifest.js","names":[],"sources":["../../src/vite/tempest-pwa-manifest.ts"],"sourcesContent":["import type { Plugin } from \"vite\";\nimport { basePrefix } from \"./base-url\";\n\n/**\n * A Vite plugin object. Typed loosely so the SDK's published declarations stay\n * free of `vite`'s internal types (which the `.d.ts` rollup can't analyze);\n * assign the result straight into a `plugins: [...]` array.\n */\nexport type TempestVitePlugin = { name: string } & Record<string, unknown>;\n\n/** Options for {@link tempestPwaManifest}. */\nexport interface TempestPwaManifestOptions {\n /** Output file name (under the build root). Default `precache-manifest.json`. */\n fileName?: string;\n /**\n * Extra URLs to precache that Vite doesn't emit into the bundle — typically\n * `public/` assets like the web manifest and icons. Default `[]`.\n *\n * Write these relative to the site root (`/icon.svg`); the resolved Vite\n * `base` is prefixed for you. An entry that already carries the base is\n * left alone, so spelling it out by hand is still correct.\n */\n additionalUrls?: string[];\n /** Emitted files matching this are skipped. Default `/\\.map$/` (source maps). */\n exclude?: RegExp;\n /** Include emitted `.html` documents (the app shell). Default `true`. */\n includeHtml?: boolean;\n /**\n * App-shell document always added to the manifest, even if Vite emits it\n * after this plugin runs. Must match `installPrecache`'s `navigateFallback`\n * so offline navigations resolve. Pass `false` to disable. Default `/index.html`.\n *\n * Like {@link TempestPwaManifestOptions.additionalUrls}, this is prefixed\n * with the resolved Vite `base`.\n */\n appShell?: string | false;\n}\n\nfunction joinBase(base: string, file: string): string {\n return `${basePrefix(base)}${file}`.replace(/([^:]\\/)\\/+/g, \"$1\");\n}\n\n/**\n * Prefix a caller-supplied, root-absolute URL with the resolved Vite `base`.\n *\n * Idempotent: a URL that already starts with the base is returned untouched,\n * so configs written before this was applied — spelling the base out by hand —\n * keep producing the same manifest instead of gaining a doubled prefix.\n */\nfunction withBase(base: string, url: string): string {\n const prefix = basePrefix(base);\n if (prefix === \"/\") return url.startsWith(\"/\") ? url : `/${url}`;\n if (url.startsWith(prefix)) return url;\n return `${prefix}${url.replace(/^\\//, \"\")}`;\n}\n\n/** Deterministic djb2 hash → hex. Stable across rebuilds with the same assets. */\nfunction hash(input: string): string {\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) >>> 0;\n }\n return h.toString(16);\n}\n\n/**\n * Vite build plugin that emits a `precache-manifest.json` listing every built\n * asset (plus any `additionalUrls`) as root-absolute URLs, with a content-based\n * `version`. It is the dependency-free counterpart to Workbox's `__WB_MANIFEST`:\n * `installPrecache` (from `tempest-react-sdk/sw`) reads this file at the service\n * worker's `install` event to cache the app shell for offline use.\n *\n * @example\n * // vite.config.ts\n * import { createViteConfig, tempestPwaManifest } from \"tempest-react-sdk/vite\";\n *\n * export default createViteConfig({\n * plugins: [tempestPwaManifest({ additionalUrls: [\"/manifest.webmanifest\", \"/icon.svg\"] })],\n * });\n */\nexport function tempestPwaManifest(options: TempestPwaManifestOptions = {}): TempestVitePlugin {\n const {\n fileName = \"precache-manifest.json\",\n additionalUrls = [],\n exclude = /\\.map$/,\n includeHtml = true,\n appShell = \"/index.html\",\n } = options;\n\n let base = \"/\";\n\n const plugin: Plugin = {\n name: \"tempest-pwa-manifest\",\n apply: \"build\",\n configResolved(config) {\n base = config.base ?? \"/\";\n },\n generateBundle(_outputOptions, bundle) {\n const urls = new Set<string>(additionalUrls.map((url) => withBase(base, url)));\n // Vite may emit index.html after this hook, so guarantee the shell.\n if (appShell) urls.add(withBase(base, appShell));\n for (const file of Object.keys(bundle)) {\n if (file === fileName) continue;\n if (exclude.test(file)) continue;\n if (!includeHtml && file.endsWith(\".html\")) continue;\n urls.add(joinBase(base, file));\n }\n\n const list = [...urls].sort();\n const version = hash(list.join(\"\\n\"));\n this.emitFile({\n type: \"asset\",\n fileName,\n source: JSON.stringify({ version, urls: list }),\n });\n },\n };\n\n return plugin as TempestVitePlugin;\n}\n"],"mappings":";;AAsCA,SAAS,EAAS,GAAc,GAAsB;CAClD,OAAO,GAAG,EAAW,CAAI,IAAI,IAAO,QAAQ,gBAAgB,IAAI;AACpE;AASA,SAAS,EAAS,GAAc,GAAqB;CACjD,IAAM,IAAS,EAAW,CAAI;CAG9B,OAFI,MAAW,MAAY,EAAI,WAAW,GAAG,IAAI,IAAM,IAAI,MACvD,EAAI,WAAW,CAAM,IAAU,IAC5B,GAAG,IAAS,EAAI,QAAQ,OAAO,EAAE;AAC5C;AAGA,SAAS,EAAK,GAAuB;CACjC,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAC9B,KAAM,KAAK,KAAK,IAAI,EAAM,WAAW,CAAC,MAAO;CAEjD,OAAO,EAAE,SAAS,EAAE;AACxB;AAiBA,SAAgB,EAAmB,IAAqC,CAAC,GAAsB;CAC3F,IAAM,EACF,cAAW,0BACX,oBAAiB,CAAC,GAClB,aAAU,UACV,iBAAc,IACd,cAAW,kBACX,GAEA,IAAO;CA6BX,OAAO;EA1BH,MAAM;EACN,OAAO;EACP,eAAe,GAAQ;GACnB,IAAO,EAAO,QAAQ;EAC1B;EACA,eAAe,GAAgB,GAAQ;GACnC,IAAM,IAAO,IAAI,IAAY,EAAe,KAAK,MAAQ,EAAS,GAAM,CAAG,CAAC,CAAC;GAE7E,AAAI,KAAU,EAAK,IAAI,EAAS,GAAM,CAAQ,CAAC;GAC/C,KAAK,IAAM,KAAQ,OAAO,KAAK,CAAM,GAC7B,MAAS,MACT,EAAQ,KAAK,CAAI,
|
|
1
|
+
{"version":3,"file":"tempest-pwa-manifest.js","names":[],"sources":["../../src/vite/tempest-pwa-manifest.ts"],"sourcesContent":["import type { Plugin } from \"vite\";\nimport { basePrefix } from \"./base-url\";\n\n/**\n * A Vite plugin object. Typed loosely so the SDK's published declarations stay\n * free of `vite`'s internal types (which the `.d.ts` rollup can't analyze);\n * assign the result straight into a `plugins: [...]` array.\n */\nexport type TempestVitePlugin = { name: string } & Record<string, unknown>;\n\n/** Options for {@link tempestPwaManifest}. */\nexport interface TempestPwaManifestOptions {\n /** Output file name (under the build root). Default `precache-manifest.json`. */\n fileName?: string;\n /**\n * Extra URLs to precache that Vite doesn't emit into the bundle — typically\n * `public/` assets like the web manifest and icons. Default `[]`.\n *\n * Write these relative to the site root (`/icon.svg`); the resolved Vite\n * `base` is prefixed for you. An entry that already carries the base is\n * left alone, so spelling it out by hand is still correct.\n */\n additionalUrls?: string[];\n /** Emitted files matching this are skipped. Default `/\\.map$/` (source maps). */\n exclude?: RegExp;\n /** Include emitted `.html` documents (the app shell). Default `true`. */\n includeHtml?: boolean;\n /**\n * App-shell document always added to the manifest, even if Vite emits it\n * after this plugin runs. Must match `installPrecache`'s `navigateFallback`\n * so offline navigations resolve. Pass `false` to disable. Default `/index.html`.\n *\n * Like {@link TempestPwaManifestOptions.additionalUrls}, this is prefixed\n * with the resolved Vite `base`.\n */\n appShell?: string | false;\n}\n\nfunction joinBase(base: string, file: string): string {\n return `${basePrefix(base)}${file}`.replace(/([^:]\\/)\\/+/g, \"$1\");\n}\n\n/**\n * Prefix a caller-supplied, root-absolute URL with the resolved Vite `base`.\n *\n * Idempotent: a URL that already starts with the base is returned untouched,\n * so configs written before this was applied — spelling the base out by hand —\n * keep producing the same manifest instead of gaining a doubled prefix.\n */\nfunction withBase(base: string, url: string): string {\n const prefix = basePrefix(base);\n if (prefix === \"/\") return url.startsWith(\"/\") ? url : `/${url}`;\n if (url.startsWith(prefix)) return url;\n return `${prefix}${url.replace(/^\\//, \"\")}`;\n}\n\n/** Deterministic djb2 hash → hex. Stable across rebuilds with the same assets. */\nfunction hash(input: string): string {\n let h = 5381;\n for (let i = 0; i < input.length; i++) {\n h = ((h << 5) + h + input.charCodeAt(i)) >>> 0;\n }\n return h.toString(16);\n}\n\n/**\n * Vite build plugin that emits a `precache-manifest.json` listing every built\n * asset (plus any `additionalUrls`) as root-absolute URLs, with a content-based\n * `version`. It is the dependency-free counterpart to Workbox's `__WB_MANIFEST`:\n * `installPrecache` (from `tempest-react-sdk/sw`) reads this file at the service\n * worker's `install` event to cache the app shell for offline use.\n *\n * @example\n * // vite.config.ts\n * import { createViteConfig, tempestPwaManifest } from \"tempest-react-sdk/vite\";\n *\n * export default createViteConfig({\n * plugins: [tempestPwaManifest({ additionalUrls: [\"/manifest.webmanifest\", \"/icon.svg\"] })],\n * });\n */\nexport function tempestPwaManifest(options: TempestPwaManifestOptions = {}): TempestVitePlugin {\n const {\n fileName = \"precache-manifest.json\",\n additionalUrls = [],\n exclude = /\\.map$/,\n includeHtml = true,\n appShell = \"/index.html\",\n } = options;\n\n let base = \"/\";\n\n const plugin: Plugin = {\n name: \"tempest-pwa-manifest\",\n apply: \"build\",\n configResolved(config) {\n base = config.base ?? \"/\";\n },\n generateBundle(_outputOptions, bundle) {\n const urls = new Set<string>(additionalUrls.map((url) => withBase(base, url)));\n // Vite may emit index.html after this hook, so guarantee the shell.\n if (appShell) urls.add(withBase(base, appShell));\n for (const file of Object.keys(bundle)) {\n if (file === fileName) continue;\n if (exclude.test(file)) continue;\n if (!includeHtml && file.endsWith(\".html\")) continue;\n urls.add(joinBase(base, file));\n }\n\n const list = [...urls].sort();\n const version = hash(list.join(\"\\n\"));\n this.emitFile({\n type: \"asset\",\n fileName,\n source: JSON.stringify({ version, urls: list }),\n });\n },\n };\n\n return plugin as TempestVitePlugin;\n}\n"],"mappings":";;AAsCA,SAAS,EAAS,GAAc,GAAsB;CAClD,OAAO,GAAG,EAAW,CAAI,IAAI,IAAO,QAAQ,gBAAgB,IAAI;AACpE;AASA,SAAS,EAAS,GAAc,GAAqB;CACjD,IAAM,IAAS,EAAW,CAAI;CAG9B,OAFI,MAAW,MAAY,EAAI,WAAW,GAAG,IAAI,IAAM,IAAI,MACvD,EAAI,WAAW,CAAM,IAAU,IAC5B,GAAG,IAAS,EAAI,QAAQ,OAAO,EAAE;AAC5C;AAGA,SAAS,EAAK,GAAuB;CACjC,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAC9B,KAAM,KAAK,KAAK,IAAI,EAAM,WAAW,CAAC,MAAO;CAEjD,OAAO,EAAE,SAAS,EAAE;AACxB;AAiBA,SAAgB,EAAmB,IAAqC,CAAC,GAAsB;CAC3F,IAAM,EACF,cAAW,0BACX,oBAAiB,CAAC,GAClB,aAAU,UACV,iBAAc,IACd,cAAW,kBACX,GAEA,IAAO;CA6BX,OAAO;EA1BH,MAAM;EACN,OAAO;EACP,eAAe,GAAQ;GACnB,IAAO,EAAO,QAAQ;EAC1B;EACA,eAAe,GAAgB,GAAQ;GACnC,IAAM,IAAO,IAAI,IAAY,EAAe,KAAK,MAAQ,EAAS,GAAM,CAAG,CAAC,CAAC;GAE7E,AAAI,KAAU,EAAK,IAAI,EAAS,GAAM,CAAQ,CAAC;GAC/C,KAAK,IAAM,KAAQ,OAAO,KAAK,CAAM,GAC7B,MAAS,MACT,EAAQ,KAAK,CAAI,MAChB,KAAe,GAAK,SAAS,OAAO,MACzC,EAAK,IAAI,EAAS,GAAM,CAAI,CAAC;GAGjC,IAAM,IAAO,CAAC,GAAG,CAAI,CAAC,CAAC,KAAK,GACtB,IAAU,EAAK,EAAK,KAAK,IAAI,CAAC;GACpC,KAAK,SAAS;IACV,MAAM;IACN;IACA,QAAQ,KAAK,UAAU;KAAE;KAAS,MAAM;IAAK,CAAC;GAClD,CAAC;EACL;CAGG;AACX"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(e){return new RTCPeerConnection({iceServers:e,bundlePolicy:`max-bundle`,rtcpMuxPolicy:`require`})}function t(e,t,n){let r=Number(e.mid);if(e.mid!==null&&Number.isInteger(r)&&n[r])return n[r];let i=t.transceivers.indexOf(e);return i>=0?n[i]??null:null}async function n(e){let t=e.pendingCandidates.splice(0,e.pendingCandidates.length);for(let n of t)try{await e.pc.addIceCandidate(n)}catch{}}async function r(e,t){if(!e.remoteReady){e.pendingCandidates.push(t);return}try{await e.pc.addIceCandidate(t)}catch{}}async function i(e,t,n){for(let[r,i]of t.entries()){let t=e.transceivers[r],a=n.get(i.name)??null;if(
|
|
1
|
+
function e(e){return new RTCPeerConnection({iceServers:e,bundlePolicy:`max-bundle`,rtcpMuxPolicy:`require`})}function t(e,t,n){let r=Number(e.mid);if(e.mid!==null&&Number.isInteger(r)&&n[r])return n[r];let i=t.transceivers.indexOf(e);return i>=0?n[i]??null:null}async function n(e){let t=e.pendingCandidates.splice(0,e.pendingCandidates.length);for(let n of t)try{await e.pc.addIceCandidate(n)}catch{}}async function r(e,t){if(!e.remoteReady){e.pendingCandidates.push(t);return}try{await e.pc.addIceCandidate(t)}catch{}}async function i(e,t,n){for(let[r,i]of t.entries()){let t=e.transceivers[r],a=n.get(i.name)??null;if(t&&a)try{await t.sender.replaceTrack(a)}catch{}}}function a(e){e.transceivers=e.pc.getTransceivers().filter(e=>e.mid!==null).sort((e,t)=>Number(e.mid)-Number(t.mid));for(let t of e.transceivers)t.direction!==`sendrecv`&&(t.direction=`sendrecv`)}exports.acceptCandidate=r,exports.adoptTransceivers=a,exports.attachLocalTracks=i,exports.createPeerConnection=e,exports.drainCandidates=n,exports.slotOf=t;
|
|
2
2
|
//# sourceMappingURL=peer-link.cjs.map
|