@srsergio/taptapp-ar 1.0.77 → 1.0.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/compiler/controller.d.ts +2 -6
  2. package/dist/compiler/controller.js +43 -44
  3. package/dist/compiler/features/auto-rotation-feature.d.ts +15 -0
  4. package/dist/compiler/features/auto-rotation-feature.js +30 -0
  5. package/dist/compiler/features/crop-detection-feature.d.ts +18 -0
  6. package/dist/compiler/features/crop-detection-feature.js +26 -0
  7. package/dist/compiler/features/feature-base.d.ts +46 -0
  8. package/dist/compiler/features/feature-base.js +1 -0
  9. package/dist/compiler/features/feature-manager.d.ts +12 -0
  10. package/dist/compiler/features/feature-manager.js +55 -0
  11. package/dist/compiler/features/one-euro-filter-feature.d.ts +15 -0
  12. package/dist/compiler/features/one-euro-filter-feature.js +37 -0
  13. package/dist/compiler/features/temporal-filter-feature.d.ts +19 -0
  14. package/dist/compiler/features/temporal-filter-feature.js +57 -0
  15. package/dist/compiler/offline-compiler.d.ts +92 -8
  16. package/dist/compiler/offline-compiler.js +3 -86
  17. package/dist/react/TaptappAR.js +3 -0
  18. package/dist/react/use-ar.js +1 -0
  19. package/package.json +1 -1
  20. package/src/compiler/FEATURES.md +40 -0
  21. package/src/compiler/controller.ts +54 -42
  22. package/src/compiler/features/auto-rotation-feature.ts +36 -0
  23. package/src/compiler/features/crop-detection-feature.ts +31 -0
  24. package/src/compiler/features/feature-base.ts +48 -0
  25. package/src/compiler/features/feature-manager.ts +65 -0
  26. package/src/compiler/features/one-euro-filter-feature.ts +44 -0
  27. package/src/compiler/features/temporal-filter-feature.ts +68 -0
  28. package/src/compiler/offline-compiler.ts +3 -94
  29. package/src/react/TaptappAR.tsx +3 -0
  30. package/src/react/use-ar.ts +1 -0
@@ -0,0 +1,68 @@
1
+ import { ControllerFeature } from "./feature-base.js";
2
+
3
+ export interface TemporalState {
4
+ showing: boolean;
5
+ trackCount: number;
6
+ trackMiss: number;
7
+ }
8
+
9
+ export class TemporalFilterFeature implements ControllerFeature {
10
+ id = "temporal-filter";
11
+ name = "Temporal Filter";
12
+ description = "Provides warmup tolerance (to avoid false positives) and miss tolerance (to maintain tracking during brief occlusions).";
13
+ enabled = true;
14
+
15
+ private states: TemporalState[] = [];
16
+ private warmupTolerance: number;
17
+ private missTolerance: number;
18
+ private onToggleShowing?: (targetIndex: number, showing: boolean) => void;
19
+
20
+ constructor(warmup: number = 2, miss: number = 5, onToggleShowing?: (targetIndex: number, showing: boolean) => void) {
21
+ this.warmupTolerance = warmup;
22
+ this.missTolerance = miss;
23
+ this.onToggleShowing = onToggleShowing;
24
+ }
25
+
26
+ private getState(targetIndex: number): TemporalState {
27
+ if (!this.states[targetIndex]) {
28
+ this.states[targetIndex] = {
29
+ showing: false,
30
+ trackCount: 0,
31
+ trackMiss: 0,
32
+ };
33
+ }
34
+ return this.states[targetIndex];
35
+ }
36
+
37
+ shouldShow(targetIndex: number, isTracking: boolean): boolean {
38
+ if (!this.enabled) return isTracking;
39
+
40
+ const state = this.getState(targetIndex);
41
+
42
+ if (!state.showing) {
43
+ if (isTracking) {
44
+ state.trackMiss = 0;
45
+ state.trackCount += 1;
46
+ if (state.trackCount > this.warmupTolerance) {
47
+ state.showing = true;
48
+ this.onToggleShowing?.(targetIndex, true);
49
+ }
50
+ } else {
51
+ state.trackCount = 0;
52
+ }
53
+ } else {
54
+ if (!isTracking) {
55
+ state.trackCount = 0;
56
+ state.trackMiss += 1;
57
+ if (state.trackMiss > this.missTolerance) {
58
+ state.showing = false;
59
+ this.onToggleShowing?.(targetIndex, false);
60
+ }
61
+ } else {
62
+ state.trackMiss = 0;
63
+ }
64
+ }
65
+
66
+ return state.showing;
67
+ }
68
+ }
@@ -11,7 +11,6 @@ import { extractTrackingFeatures } from "./tracker/extract-utils.js";
11
11
  import { DetectorLite } from "./detector/detector-lite.js";
12
12
  import { build as hierarchicalClusteringBuild } from "./matching/hierarchical-clustering.js";
13
13
  import * as msgpack from "@msgpack/msgpack";
14
- import { WorkerPool } from "./utils/worker-pool.js";
15
14
 
16
15
  // Detect environment
17
16
  const isNode = typeof process !== "undefined" &&
@@ -22,40 +21,9 @@ const CURRENT_VERSION = 7; // Protocol v7: Moonshot - 4-bit Packed Tracking Data
22
21
 
23
22
  export class OfflineCompiler {
24
23
  data: any = null;
25
- workerPool: WorkerPool | null = null;
26
24
 
27
25
  constructor() {
28
- // Workers only in Node.js
29
- if (!isNode) {
30
- console.log("🌐 OfflineCompiler: Browser mode (no workers)");
31
- }
32
- }
33
-
34
- async _initNodeWorkers() {
35
- try {
36
- const pathModule = "path";
37
- const urlModule = "url";
38
- const osModule = "os";
39
- const workerThreadsModule = "node:worker_threads";
40
-
41
- const [path, url, os, { Worker }] = await Promise.all([
42
- import(/* @vite-ignore */ pathModule),
43
- import(/* @vite-ignore */ urlModule),
44
- import(/* @vite-ignore */ osModule),
45
- import(/* @vite-ignore */ workerThreadsModule)
46
- ]);
47
-
48
- const __filename = url.fileURLToPath(import.meta.url);
49
- const __dirname = path.dirname(__filename);
50
- const workerPath = path.join(__dirname, "node-worker.js");
51
-
52
- // Limit workers to avoid freezing system
53
- const numWorkers = Math.min(os.cpus().length, 4);
54
-
55
- this.workerPool = new WorkerPool(workerPath, numWorkers, Worker);
56
- } catch (e) {
57
- console.log("⚡ OfflineCompiler: Running without workers (initialization failed)", e);
58
- }
26
+ console.log("⚡ OfflineCompiler: Main thread mode (no workers)");
59
27
  }
60
28
 
61
29
  async compileImageTargets(images: any[], progressCallback: (p: number) => void) {
@@ -108,25 +76,7 @@ export class OfflineCompiler {
108
76
  }
109
77
 
110
78
  async _compileTarget(targetImages: any[], progressCallback: (p: number) => void) {
111
- if (isNode) await this._initNodeWorkers();
112
-
113
- if (this.workerPool) {
114
- const progressMap = new Float32Array(targetImages.length);
115
- const wrappedPromises = targetImages.map((targetImage: any, index: number) => {
116
- return this.workerPool!.runTask({
117
- type: 'compile-all', // 🚀 MOONSHOT: Combined task
118
- targetImage,
119
- onProgress: (p: number) => {
120
- progressMap[index] = p;
121
- const sum = progressMap.reduce((a, b) => a + b, 0);
122
- progressCallback(sum / targetImages.length);
123
- }
124
- });
125
- });
126
- return Promise.all(wrappedPromises);
127
- }
128
-
129
- // Fallback or non-worker implementation: run match and track sequentially
79
+ // Run match and track sequentially to match browser behavior exactly
130
80
  const matchingResults = await this._compileMatch(targetImages, (p) => progressCallback(p * 0.5));
131
81
  const trackingResults = await this._compileTrack(targetImages, (p) => progressCallback(50 + p * 0.5));
132
82
 
@@ -140,27 +90,6 @@ export class OfflineCompiler {
140
90
  const percentPerImage = 100 / targetImages.length;
141
91
  let currentPercent = 0;
142
92
 
143
- if (isNode) await this._initNodeWorkers();
144
- if (this.workerPool) {
145
- const progressMap = new Float32Array(targetImages.length);
146
-
147
- const wrappedPromises = targetImages.map((targetImage: any, index: number) => {
148
- return this.workerPool!.runTask({
149
- type: 'match',
150
- targetImage,
151
- percentPerImage,
152
- basePercent: 0,
153
- onProgress: (p: number) => {
154
- progressMap[index] = p;
155
- const sum = progressMap.reduce((a, b) => a + b, 0);
156
- progressCallback(sum);
157
- }
158
- });
159
- });
160
-
161
- return Promise.all(wrappedPromises);
162
- }
163
-
164
93
  const results = [];
165
94
  for (let i = 0; i < targetImages.length; i++) {
166
95
  const targetImage = targetImages[i];
@@ -201,24 +130,6 @@ export class OfflineCompiler {
201
130
  const percentPerImage = 100 / targetImages.length;
202
131
  let currentPercent = 0;
203
132
 
204
- if (this.workerPool) {
205
- const progressMap = new Float32Array(targetImages.length);
206
- const wrappedPromises = targetImages.map((targetImage: any, index: number) => {
207
- return this.workerPool!.runTask({
208
- type: 'compile',
209
- targetImage,
210
- percentPerImage,
211
- basePercent: 0,
212
- onProgress: (p: number) => {
213
- progressMap[index] = p;
214
- const sum = progressMap.reduce((a, b) => a + b, 0);
215
- progressCallback(sum);
216
- }
217
- });
218
- });
219
- return Promise.all(wrappedPromises);
220
- }
221
-
222
133
  const results = [];
223
134
  for (let i = 0; i < targetImages.length; i++) {
224
135
  const targetImage = targetImages[i];
@@ -480,9 +391,7 @@ export class OfflineCompiler {
480
391
  }
481
392
 
482
393
  async destroy() {
483
- if (this.workerPool) {
484
- await this.workerPool.destroy();
485
- }
394
+ // No workers to destroy
486
395
  }
487
396
 
488
397
 
@@ -169,6 +169,9 @@ export const TaptappAR: React.FC<TaptappARProps> = ({
169
169
  display: block;
170
170
  width: 100%;
171
171
  height: auto;
172
+ opacity: 0;
173
+ pointer-events: none;
174
+ transition: opacity 0.3s ease;
172
175
  }
173
176
  `}</style>
174
177
  </div>
@@ -52,6 +52,7 @@ export const useAR = (config: ARConfig): UseARReturn => {
52
52
  targetSrc: config.targetTaarSrc,
53
53
  overlay: overlayRef.current!,
54
54
  scale: config.scale,
55
+ debug: false,
55
56
  onFound: async ({ targetIndex }) => {
56
57
  console.log(`🎯 Target ${targetIndex} detected!`);
57
58
  if (!isMounted) return;