@srsergio/taptapp-ar 1.1.4 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -1
- package/dist/core/embeddings/bridge.d.ts +25 -0
- package/dist/core/embeddings/bridge.js +1 -0
- package/dist/core/embeddings/image-embedding.d.ts +185 -0
- package/dist/core/embeddings/image-embedding.js +1 -0
- package/dist/core/embeddings/index.d.ts +2 -0
- package/dist/core/embeddings/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
- [Raw Controller](#3-raw-controller-advanced--custom-engines)
|
|
24
24
|
- [Vanilla JS (SimpleAR)](#4-vanilla-js-no-framework-)
|
|
25
25
|
- [🏗️ Protocol V7](#️-protocol-v7-moonshot-packed-format)
|
|
26
|
+
- [🔍 Visual Search & Embeddings](#-visual-search--embeddings-new)
|
|
26
27
|
- [📄 License & Credits](#-license--credits)
|
|
27
28
|
|
|
28
29
|
---
|
|
@@ -269,7 +270,53 @@ TapTapp AR uses a proprietary **Nanite-style Vision Codec** that is significantl
|
|
|
269
270
|
|
|
270
271
|
---
|
|
271
272
|
|
|
272
|
-
##
|
|
273
|
+
## � Visual Search & Embeddings (NEW!) 🚀
|
|
274
|
+
|
|
275
|
+
TapTapp AR now includes a state-of-the-art **Image Embedding** system based on Hyperdimensional Computing (HDC). This allows you to convert any image into a tiny mathematical fingerprint (vector) for ultra-fast visual search, deduplication, and clustering.
|
|
276
|
+
|
|
277
|
+
### 🍱 Embedding Modes
|
|
278
|
+
| Mode | Size | Speed | Recommendation |
|
|
279
|
+
| :--- | :--- | :--- | :--- |
|
|
280
|
+
| `micro` | 4 Bytes | 10M+ ops/s | Extreme IoT |
|
|
281
|
+
| **`compact`** | **16 Bytes** | **44M+ ops/s** | 🏆 **Best for Mega-Databases** |
|
|
282
|
+
| `standard`| 32 Bytes | 18M+ ops/s | Balanced AR |
|
|
283
|
+
| `full` | 128 Bytes| 7M+ ops/s | Maximum Precision |
|
|
284
|
+
|
|
285
|
+
### 🚀 Usage Example (RAG Standard 🧠)
|
|
286
|
+
Create visual embeddings and compare them just like you do with Text LLMs:
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
import { visualSearch } from '@srsergio/taptapp-ar';
|
|
290
|
+
|
|
291
|
+
// 1. Get a Dense Vector (Array of numbers) - LLM Standard
|
|
292
|
+
const embedding = await visualSearch.compute('product.jpg');
|
|
293
|
+
const vector = embedding.toFloatArray(); // [1.0, 0.0, 1.0, ...]
|
|
294
|
+
|
|
295
|
+
// 2. Similarity Search (Self-contained)
|
|
296
|
+
const score = await visualSearch.compare('item1.jpg', 'item2.jpg');
|
|
297
|
+
console.log(`Visual Match: ${score * 100}%`);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 🗄️ Vector Database Integration
|
|
301
|
+
Use your favorite vector database (Pinecone, Milvus, Weaviate, or `pgvector`) with the standard array format:
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
// Example: Storing in a standard Vector DB
|
|
305
|
+
await vectorDB.insert({
|
|
306
|
+
id: 'image_42',
|
|
307
|
+
vector: Array.from(embedding.toFloatArray()),
|
|
308
|
+
metadata: { name: 'Vintage Camera', category: 'Electronics' }
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Example: Searching in PostgreSQL (pgvector)
|
|
312
|
+
// SELECT * FROM items ORDER BY embedding <=> '[1,0,1,1...]' LIMIT 5;
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## �📄 License & Credits
|
|
273
320
|
|
|
274
321
|
This project is licensed under the **Fair Source License v0.9**.
|
|
275
322
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ImageSearchBridge - A high-level helper to make image embeddings
|
|
3
|
+
* extremely easy to use for developers.
|
|
4
|
+
*/
|
|
5
|
+
export class ImageSearchBridge {
|
|
6
|
+
constructor(mode?: string);
|
|
7
|
+
embedder: ImageEmbedder;
|
|
8
|
+
/**
|
|
9
|
+
* Compute an embedding from almost any source
|
|
10
|
+
* @param {string|HTMLImageElement|HTMLCanvasElement|Uint8Array|Buffer} source
|
|
11
|
+
* @returns {Promise<ImageEmbedding>}
|
|
12
|
+
*/
|
|
13
|
+
compute(source: string | HTMLImageElement | HTMLCanvasElement | Uint8Array | Buffer): Promise<ImageEmbedding>;
|
|
14
|
+
/**
|
|
15
|
+
* Compare two image sources directly
|
|
16
|
+
*/
|
|
17
|
+
compare(sourceA: any, sourceB: any): Promise<number>;
|
|
18
|
+
_rgbaToGrayscale(rgba: any, w: any, h: any): Float32Array<ArrayBuffer>;
|
|
19
|
+
_loadImageBrowser(url: any): Promise<any>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Easy-to-use factory for quick tasks
|
|
23
|
+
*/
|
|
24
|
+
export const visualSearch: ImageSearchBridge;
|
|
25
|
+
import { ImageEmbedder } from './image-embedding.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ImageEmbedder as e}from"./image-embedding.js";export class ImageSearchBridge{constructor(t="compact"){this.embedder=new e(t)}async compute(e){let t=null,a=0,r=0;if("string"==typeof e){if("undefined"==typeof document)throw new Error("URL loading in Node requires a fetch/loading utility. Please provide a Buffer or Uint8Array.");e=await this._loadImageBrowser(e)}if("undefined"!=typeof document&&(e instanceof HTMLImageElement||e instanceof HTMLCanvasElement||e instanceof ImageBitmap)){const o=document.createElement("canvas");a=e.width||e.videoWidth,r=e.height||e.videoHeight,o.width=a,o.height=r;const n=o.getContext("2d");n.drawImage(e,0,0);const i=n.getImageData(0,0,a,r).data;t=this._rgbaToGrayscale(i,a,r)}if(!t&&(e instanceof Uint8Array||"undefined"!=typeof Buffer&&Buffer.isBuffer(e))){if(!(e.data&&e.width&&e.height))throw new Error("Raw data source must be an object { data, width, height }");t=e.data,a=e.width,r=e.height}if(!t)throw new Error("Unsupported image source type");return this.embedder.embed(t,a,r)}async compare(e,t){const a=await this.compute(e),r=await this.compute(t);return this.embedder.compare(a,r)}_rgbaToGrayscale(e,t,a){const r=new Float32Array(t*a);for(let o=0;o<t*a;o++){const t=4*o;r[o]=(.299*e[t]+.587*e[t+1]+.114*e[t+2])/255}return r}_loadImageBrowser(e){return new Promise((t,a)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>t(r),r.onerror=a,r.src=e})}}export const visualSearch=new ImageSearchBridge("compact");
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genera embedding de una imagen en un solo paso
|
|
3
|
+
*
|
|
4
|
+
* @param {Float32Array|Uint8Array} imageData
|
|
5
|
+
* @param {number} width
|
|
6
|
+
* @param {number} height
|
|
7
|
+
* @param {string} mode - 'micro' | 'compact' | 'standard' | 'full'
|
|
8
|
+
* @returns {ImageEmbedding}
|
|
9
|
+
*/
|
|
10
|
+
export function embedImage(imageData: Float32Array | Uint8Array, width: number, height: number, mode?: string): ImageEmbedding;
|
|
11
|
+
/**
|
|
12
|
+
* Compara dos imágenes directamente
|
|
13
|
+
*
|
|
14
|
+
* @param {Float32Array} img1Data
|
|
15
|
+
* @param {number} img1Width
|
|
16
|
+
* @param {number} img1Height
|
|
17
|
+
* @param {Float32Array} img2Data
|
|
18
|
+
* @param {number} img2Width
|
|
19
|
+
* @param {number} img2Height
|
|
20
|
+
* @param {string} mode
|
|
21
|
+
* @returns {number} Similitud 0-1
|
|
22
|
+
*/
|
|
23
|
+
export function compareImages(img1Data: Float32Array, img1Width: number, img1Height: number, img2Data: Float32Array, img2Width: number, img2Height: number, mode?: string): number;
|
|
24
|
+
/**
|
|
25
|
+
* Detecta si dos imágenes son duplicados (o casi-duplicados)
|
|
26
|
+
*
|
|
27
|
+
* @param {ImageEmbedding} emb1
|
|
28
|
+
* @param {ImageEmbedding} emb2
|
|
29
|
+
* @param {number} threshold - Umbral de similitud (default: 0.85)
|
|
30
|
+
* @returns {boolean}
|
|
31
|
+
*/
|
|
32
|
+
export function isDuplicate(emb1: ImageEmbedding, emb2: ImageEmbedding, threshold?: number): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Generador de Image Embeddings
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* const embedder = new ImageEmbedder('standard');
|
|
38
|
+
*
|
|
39
|
+
* // Generar embedding de una imagen
|
|
40
|
+
* const embedding = embedder.embed(imageData, width, height);
|
|
41
|
+
*
|
|
42
|
+
* // Comparar dos imágenes
|
|
43
|
+
* const similarity = embedder.compare(embedding1, embedding2);
|
|
44
|
+
*
|
|
45
|
+
* // Buscar en base de datos
|
|
46
|
+
* const results = embedder.search(queryEmbedding, database, topK=10);
|
|
47
|
+
*/
|
|
48
|
+
export class ImageEmbedder {
|
|
49
|
+
constructor(mode?: string);
|
|
50
|
+
config: any;
|
|
51
|
+
basis: any;
|
|
52
|
+
mode: string;
|
|
53
|
+
/**
|
|
54
|
+
* Genera un embedding de una imagen en escala de grises
|
|
55
|
+
*
|
|
56
|
+
* @param {Float32Array|Uint8Array} imageData - Datos de imagen (grayscale)
|
|
57
|
+
* @param {number} width - Ancho de la imagen
|
|
58
|
+
* @param {number} height - Alto de la imagen
|
|
59
|
+
* @returns {ImageEmbedding} Objeto embedding
|
|
60
|
+
*/
|
|
61
|
+
embed(imageData: Float32Array | Uint8Array, width: number, height: number): ImageEmbedding;
|
|
62
|
+
/**
|
|
63
|
+
* Compara dos embeddings y retorna similitud [0, 1]
|
|
64
|
+
*
|
|
65
|
+
* Usa una métrica ajustada donde:
|
|
66
|
+
* - Idénticos = 1.0
|
|
67
|
+
* - Aleatorios (50% hamming) = 0.0
|
|
68
|
+
* - Completamente opuestos = -1.0 (pero clampeamos a 0)
|
|
69
|
+
*
|
|
70
|
+
* @param {ImageEmbedding} emb1
|
|
71
|
+
* @param {ImageEmbedding} emb2
|
|
72
|
+
* @returns {number} Similitud entre 0 (diferente/random) y 1 (idéntico)
|
|
73
|
+
*/
|
|
74
|
+
compare(emb1: ImageEmbedding, emb2: ImageEmbedding): number;
|
|
75
|
+
/**
|
|
76
|
+
* Busca los embeddings más similares en una base de datos
|
|
77
|
+
*
|
|
78
|
+
* @param {ImageEmbedding} query - Embedding a buscar
|
|
79
|
+
* @param {ImageEmbedding[]} database - Array de embeddings
|
|
80
|
+
* @param {number} topK - Número de resultados a retornar
|
|
81
|
+
* @returns {Array<{index: number, similarity: number}>} Resultados ordenados
|
|
82
|
+
*/
|
|
83
|
+
search(query: ImageEmbedding, database: ImageEmbedding[], topK?: number): Array<{
|
|
84
|
+
index: number;
|
|
85
|
+
similarity: number;
|
|
86
|
+
}>;
|
|
87
|
+
/**
|
|
88
|
+
* Agrupa embeddings por similitud (clustering)
|
|
89
|
+
*
|
|
90
|
+
* @param {ImageEmbedding[]} embeddings
|
|
91
|
+
* @param {number} threshold - Umbral de similitud para agrupar (0-1)
|
|
92
|
+
* @returns {number[]} Array de cluster IDs para cada embedding
|
|
93
|
+
*/
|
|
94
|
+
cluster(embeddings: ImageEmbedding[], threshold?: number): number[];
|
|
95
|
+
/**
|
|
96
|
+
* Comprime el hypervector HDC al tamaño de salida deseado
|
|
97
|
+
*/
|
|
98
|
+
_compressToSize(hv: any, targetBits: any): Uint32Array<any>;
|
|
99
|
+
/**
|
|
100
|
+
* Weighted Bundle: Combina hypervectors con pesos
|
|
101
|
+
* Features con mayor score contribuyen más al resultado final
|
|
102
|
+
*/
|
|
103
|
+
_weightedBundle(hvs: any, weights: any): Uint32Array<ArrayBuffer>;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Representa un embedding de imagen
|
|
107
|
+
*/
|
|
108
|
+
export class ImageEmbedding {
|
|
109
|
+
/**
|
|
110
|
+
* Crea un embedding desde bytes
|
|
111
|
+
* @param {Uint8Array} bytes
|
|
112
|
+
* @returns {ImageEmbedding}
|
|
113
|
+
*/
|
|
114
|
+
static fromBytes(bytes: Uint8Array): ImageEmbedding;
|
|
115
|
+
/**
|
|
116
|
+
* Crea un embedding desde Base64
|
|
117
|
+
* @param {string} base64
|
|
118
|
+
* @returns {ImageEmbedding}
|
|
119
|
+
*/
|
|
120
|
+
static fromBase64(base64: string): ImageEmbedding;
|
|
121
|
+
constructor(vector: any, metadata?: {});
|
|
122
|
+
vector: any;
|
|
123
|
+
metadata: {};
|
|
124
|
+
/**
|
|
125
|
+
* Serializa el embedding a bytes para storage
|
|
126
|
+
* @returns {Uint8Array}
|
|
127
|
+
*/
|
|
128
|
+
toBytes(): Uint8Array;
|
|
129
|
+
/**
|
|
130
|
+
* Serializa a Base64 para transmisión
|
|
131
|
+
* @returns {string}
|
|
132
|
+
*/
|
|
133
|
+
toBase64(): string;
|
|
134
|
+
/**
|
|
135
|
+
* Serializa a hex string
|
|
136
|
+
* @returns {string}
|
|
137
|
+
*/
|
|
138
|
+
toHex(): string;
|
|
139
|
+
/**
|
|
140
|
+
* Convierte el vector binario a un array de floats (0.0 o 1.0)
|
|
141
|
+
* Útil para compatibilidad con bases de datos vectoriales que esperan arrays de números (como LLMs)
|
|
142
|
+
*
|
|
143
|
+
* @returns {Float32Array}
|
|
144
|
+
*/
|
|
145
|
+
toFloatArray(): Float32Array;
|
|
146
|
+
/**
|
|
147
|
+
* Número de bits del embedding
|
|
148
|
+
*/
|
|
149
|
+
get bits(): number;
|
|
150
|
+
/**
|
|
151
|
+
* Número de bytes del embedding
|
|
152
|
+
*/
|
|
153
|
+
get bytes(): number;
|
|
154
|
+
}
|
|
155
|
+
export namespace EMBEDDING_CONFIGS {
|
|
156
|
+
namespace micro {
|
|
157
|
+
let outputBits: number;
|
|
158
|
+
let maxFeatures: number;
|
|
159
|
+
let pyramidOctaves: number;
|
|
160
|
+
}
|
|
161
|
+
namespace compact {
|
|
162
|
+
let outputBits_1: number;
|
|
163
|
+
export { outputBits_1 as outputBits };
|
|
164
|
+
let maxFeatures_1: number;
|
|
165
|
+
export { maxFeatures_1 as maxFeatures };
|
|
166
|
+
let pyramidOctaves_1: number;
|
|
167
|
+
export { pyramidOctaves_1 as pyramidOctaves };
|
|
168
|
+
}
|
|
169
|
+
namespace standard {
|
|
170
|
+
let outputBits_2: number;
|
|
171
|
+
export { outputBits_2 as outputBits };
|
|
172
|
+
let maxFeatures_2: number;
|
|
173
|
+
export { maxFeatures_2 as maxFeatures };
|
|
174
|
+
let pyramidOctaves_2: number;
|
|
175
|
+
export { pyramidOctaves_2 as pyramidOctaves };
|
|
176
|
+
}
|
|
177
|
+
namespace full {
|
|
178
|
+
let outputBits_3: number;
|
|
179
|
+
export { outputBits_3 as outputBits };
|
|
180
|
+
let maxFeatures_3: number;
|
|
181
|
+
export { maxFeatures_3 as maxFeatures };
|
|
182
|
+
let pyramidOctaves_3: number;
|
|
183
|
+
export { pyramidOctaves_3 as pyramidOctaves };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{DetectorLite as t}from"../detector/detector-lite.js";import{generateBasis as e,projectDescriptor as r,bundle as o,compressToSignature as s,HDC_DIMENSION as n,HDC_WORDS as i}from"../matching/hdc.js";import{HDC_SEED as a}from"../protocol.js";const c={micro:{outputBits:32,maxFeatures:100,pyramidOctaves:3},compact:{outputBits:128,maxFeatures:200,pyramidOctaves:4},standard:{outputBits:256,maxFeatures:300,pyramidOctaves:5},full:{outputBits:1024,maxFeatures:500,pyramidOctaves:6}};let m=null;export class ImageEmbedder{constructor(t="standard"){this.config=c[t]||c.standard,this.basis=(m||(m=e(a,n)),m),this.mode=t}embed(e,s,n){const a=performance.now(),c=new t(s,n,{useGPU:!0,useLSH:!0,maxFeaturesPerBucket:Math.ceil(this.config.maxFeatures/100),maxOctaves:this.config.pyramidOctaves}),{featurePoints:m}=c.detect(e),d=m.sort((t,e)=>(e.score||0)-(t.score||0)).slice(0,this.config.maxFeatures);if(0===d.length)return new ImageEmbedding(new Uint32Array(this.config.outputBits/32),{featureCount:0,mode:this.mode,timeMs:performance.now()-a});const u=[];for(const t of d){if(!t.descriptors||t.descriptors.length<2)continue;const e=t.descriptors instanceof Uint32Array?t.descriptors:new Uint32Array([t.descriptors[0]|t.descriptors[1]<<8|t.descriptors[2]<<16|t.descriptors[3]<<24,t.descriptors[4]|t.descriptors[5]<<8|t.descriptors[6]<<16|t.descriptors[7]<<24]),o=r(e,this.basis),i=Math.floor(t.x/s*3),a=Math.floor(t.y/n*3),c=2654435769*(Math.min(8,Math.max(0,3*a+i))+1);for(let t=0;t<o.length;t++){let e=c+2246822507*t|0;e=Math.imul(e^e>>>16,36094177),e=Math.imul(e^e>>>13,3266489909),e=(e^e>>>16)>>>0,o[t]^=e}u.push(o)}const l=u.length>0?o(u):new Uint32Array(i),h=this._compressToSize(l,this.config.outputBits),f=performance.now()-a;return new ImageEmbedding(h,{featureCount:d.length,mode:this.mode,timeMs:f,width:s,height:n})}compare(t,e){const r=t.vector||t,o=e.vector||e;if(r.length!==o.length)throw new Error("Embeddings must have same dimension");let s=0;const n=32*r.length;for(let t=0;t<r.length;t++)s+=d(r[t]^o[t]);const i=s/(n/2);return Math.max(0,1-i)}search(t,e,r=10){const o=[];for(let r=0;r<e.length;r++){const s=this.compare(t,e[r]);o.push({index:r,similarity:s})}return o.sort((t,e)=>e.similarity-t.similarity),o.slice(0,r)}cluster(t,e=.7){const r=t.length,o=new Array(r).fill(-1);let s=0;for(let n=0;n<r;n++)if(-1===o[n]){o[n]=s;for(let i=n+1;i<r;i++)-1===o[i]&&this.compare(t[n],t[i])>=e&&(o[i]=s);s++}return o}_compressToSize(t,e){const r=e/32;if(r>=i)return new Uint32Array(t.buffer,0,r);const o=new Uint32Array(r);if(32===e)o[0]=s(t);else{const e=Math.ceil(i/r);for(let s=0;s<r;s++){let r=0;for(let o=0;o<e;o++){const n=s*e+o;n<i&&(r^=t[n])}o[s]=(r<<s%32|r>>>32-s%32)>>>0}}return o}_weightedBundle(t,e){const r=new Uint32Array(i),o=e.reduce((t,e)=>t+e,0),s=e.map(t=>t/o),a=new Float32Array(n);for(let e=0;e<t.length;e++){const r=t[e],o=s[e];for(let t=0;t<n;t++)r[t>>>5]&1<<(31&t)&&(a[t]+=o)}for(let t=0;t<n;t++)a[t]>.5&&(r[t>>>5]|=1<<(31&t));return r}}export class ImageEmbedding{constructor(t,e={}){this.vector=t,this.metadata=e}toBytes(){return new Uint8Array(this.vector.buffer)}static fromBytes(t){const e=new Uint32Array(t.buffer);return new ImageEmbedding(e)}toBase64(){const t=this.toBytes();let e="";for(let r=0;r<t.length;r++)e+=String.fromCharCode(t[r]);return btoa(e)}static fromBase64(t){const e=atob(t),r=new Uint8Array(e.length);for(let t=0;t<e.length;t++)r[t]=e.charCodeAt(t);return ImageEmbedding.fromBytes(r)}toHex(){return Array.from(this.vector).map(t=>t.toString(16).padStart(8,"0")).join("")}toFloatArray(){const t=this.bits,e=new Float32Array(t);for(let r=0;r<t;r++){const t=r>>>5,o=31&r;e[r]=this.vector[t]&1<<o?1:0}return e}get bits(){return 32*this.vector.length}get bytes(){return 4*this.vector.length}}export function embedImage(t,e,r,o="standard"){return new ImageEmbedder(o).embed(t,e,r)}export function compareImages(t,e,r,o,s,n,i="standard"){const a=new ImageEmbedder(i),c=a.embed(t,e,r),m=a.embed(o,s,n);return a.compare(c,m)}export function isDuplicate(t,e,r=.85){return(new ImageEmbedder).compare(t,e)>=r}function d(t){return 16843009*((t=(858993459&(t-=t>>1&1431655765))+(t>>2&858993459))+(t>>4)&252645135)>>24}export{c as EMBEDDING_CONFIGS};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{ImageEmbedder,ImageEmbedding,embedImage,compareImages,isDuplicate,EMBEDDING_CONFIGS}from"./image-embedding.js";export{ImageSearchBridge,visualSearch}from"./bridge.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,5 @@ export * from "./react/use-ar.js";
|
|
|
4
4
|
export * from "./compiler/offline-compiler.js";
|
|
5
5
|
export { Controller } from "./runtime/controller.js";
|
|
6
6
|
export { createTracker, startTracking } from "./runtime/track.js";
|
|
7
|
+
export { ImageEmbedder, ImageSearchBridge, visualSearch } from "./core/embeddings/index.js";
|
|
7
8
|
export * as protocol from "./core/protocol.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./react/types.js";export*from"./react/TaptappAR.js";export*from"./react/use-ar.js";export*from"./compiler/offline-compiler.js";export{Controller}from"./runtime/controller.js";export{createTracker,startTracking}from"./runtime/track.js";export*as protocol from"./core/protocol.js";
|
|
1
|
+
export*from"./react/types.js";export*from"./react/TaptappAR.js";export*from"./react/use-ar.js";export*from"./compiler/offline-compiler.js";export{Controller}from"./runtime/controller.js";export{createTracker,startTracking}from"./runtime/track.js";export{ImageEmbedder,ImageSearchBridge,visualSearch}from"./core/embeddings/index.js";export*as protocol from"./core/protocol.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@srsergio/taptapp-ar",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "Ultra-fast Augmented Reality (AR) SDK for Node.js and Browser. Image tracking with 100% pure JavaScript, zero-dependencies, and high-performance compilation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"augmented reality",
|