@symbiote-native/tracking-transparency 3.0.2 → 3.1.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/README.md +78 -73
- package/build/angular/index.d.ts +1 -1
- package/build/angular/index.js +2 -3
- package/build/angular/tracking-permissions.service.d.ts +5 -0
- package/build/angular/{services/permissions.service/index.js → tracking-permissions.service.js} +13 -48
- package/build/core/tracking-permission-api.d.ts +5 -0
- package/build/core/tracking-permission-api.js +7 -0
- package/build/react/index.d.ts +1 -1
- package/build/react/index.js +2 -5
- package/build/react/use-tracking-permissions.d.ts +8 -0
- package/build/react/use-tracking-permissions.js +4 -0
- package/build/solid/index.d.ts +1 -1
- package/build/solid/index.js +2 -6
- package/build/solid/use-tracking-permissions.d.ts +9 -0
- package/build/solid/use-tracking-permissions.js +4 -0
- package/build/svelte/index.d.ts +1 -1
- package/build/svelte/index.js +2 -5
- package/build/svelte/use-tracking-permissions.svelte.d.ts +8 -0
- package/build/svelte/use-tracking-permissions.svelte.js +4 -0
- package/build/vue/index.d.ts +1 -1
- package/build/vue/index.js +2 -5
- package/build/vue/use-tracking-permissions.d.ts +9 -0
- package/build/vue/use-tracking-permissions.js +4 -0
- package/build-ngc/angular/index.d.ts +1 -1
- package/build-ngc/angular/index.js +2 -3
- package/build-ngc/angular/index.js.map +1 -1
- package/build-ngc/angular/tracking-permissions.service.d.ts +8 -0
- package/build-ngc/angular/tracking-permissions.service.js +17 -0
- package/build-ngc/angular/tracking-permissions.service.js.map +1 -0
- package/build-ngc/core/tracking-permission-api.d.ts +5 -0
- package/build-ngc/core/tracking-permission-api.js +8 -0
- package/build-ngc/core/tracking-permission-api.js.map +1 -0
- package/package.json +15 -15
- package/src/angular/index.ts +2 -3
- package/src/angular/tracking-permissions.service.ts +16 -0
- package/src/core/tracking-permission-api.ts +12 -0
- package/src/react/index.ts +5 -6
- package/src/react/use-tracking-permissions.ts +16 -0
- package/src/solid/index.ts +5 -7
- package/src/solid/use-tracking-permissions.ts +17 -0
- package/src/svelte/index.ts +5 -6
- package/src/svelte/svelte-compile.test-helper.ts +6 -0
- package/src/svelte/use-tracking-permissions.svelte.ts +16 -0
- package/src/vue/index.ts +5 -6
- package/src/vue/use-tracking-permissions.ts +17 -0
- package/build/angular/services/permissions.service/index.d.ts +0 -12
- package/build/react/hooks/use-permissions/index.d.ts +0 -7
- package/build/react/hooks/use-permissions/index.js +0 -43
- package/build/solid/primitives/create-permissions.d.ts +0 -8
- package/build/solid/primitives/create-permissions.js +0 -41
- package/build/svelte/runes/use-permissions.svelte.d.ts +0 -7
- package/build/svelte/runes/use-permissions.svelte.js +0 -49
- package/build/vue/composables/use-permissions/index.d.ts +0 -8
- package/build/vue/composables/use-permissions/index.js +0 -33
- package/build-ngc/angular/services/permissions.service/index.d.ts +0 -15
- package/build-ngc/angular/services/permissions.service/index.js +0 -55
- package/build-ngc/angular/services/permissions.service/index.js.map +0 -1
- package/src/angular/services/permissions.service/index.ts +0 -57
- package/src/react/hooks/use-permissions/index.ts +0 -57
- package/src/solid/primitives/create-permissions.ts +0 -56
- package/src/svelte/runes/use-permissions.svelte.ts +0 -63
- package/src/vue/composables/use-permissions/index.ts +0 -47
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// `methods` every adapter's `useTrackingPermissions` binds to the shared
|
|
2
|
+
// `@symbiote-native/{react,vue,solid,svelte}` `createPermissionHook` factory
|
|
3
|
+
import { getTrackingPermissionsAsync, requestTrackingPermissionsAsync, } from './tracking-transparency';
|
|
4
|
+
export const trackingPermissionMethods = {
|
|
5
|
+
getMethod: getTrackingPermissionsAsync,
|
|
6
|
+
requestMethod: requestTrackingPermissionsAsync,
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=tracking-permission-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracking-permission-api.js","sourceRoot":"","sources":["../../src/core/tracking-permission-api.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,6EAA6E;AAE7E,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AAEjC,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,SAAS,EAAE,2BAA2B;IACtC,aAAa,EAAE,+BAA+B;CAC/C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/tracking-transparency",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "expo-tracking-transparency wrapped for SymbioteNative — one framework-agnostic core, built once and reachable from the React, Vue, Svelte, Solid, and Angular adapters. iOS App Tracking Transparency prompt (permission get/request, always-granted on Android/web) plus the advertising-ID getter.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
},
|
|
70
70
|
"dependencies": {
|
|
71
71
|
"expo-tracking-transparency": "57.0.1",
|
|
72
|
-
"expo-modules-core": "57.0.
|
|
72
|
+
"expo-modules-core": "57.0.20"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"@angular/core": ">=20",
|
|
@@ -79,12 +79,12 @@
|
|
|
79
79
|
"solid-js": ">=1.9.0",
|
|
80
80
|
"svelte": ">=5.56.0",
|
|
81
81
|
"vue": ">=3.5.0",
|
|
82
|
-
"@symbiote-native/
|
|
83
|
-
"@symbiote-native/
|
|
84
|
-
"@symbiote-native/
|
|
85
|
-
"@symbiote-native/vue": "^3.0
|
|
86
|
-
"@symbiote-native/
|
|
87
|
-
"@symbiote-native/
|
|
82
|
+
"@symbiote-native/engine": "^1.5.0",
|
|
83
|
+
"@symbiote-native/react": "^3.2.0",
|
|
84
|
+
"@symbiote-native/angular": "^3.2.0",
|
|
85
|
+
"@symbiote-native/vue": "^3.2.0",
|
|
86
|
+
"@symbiote-native/svelte": "^3.1.0",
|
|
87
|
+
"@symbiote-native/solid": "^3.1.0"
|
|
88
88
|
},
|
|
89
89
|
"peerDependenciesMeta": {
|
|
90
90
|
"@symbiote-native/angular": {
|
|
@@ -132,13 +132,13 @@
|
|
|
132
132
|
"solid-js": "^1.9.14",
|
|
133
133
|
"svelte": "^5.56.0",
|
|
134
134
|
"typescript": "~6.0.0",
|
|
135
|
-
"@symbiote-native/
|
|
136
|
-
"@symbiote-native/react": "3.0
|
|
137
|
-
"@symbiote-native/
|
|
138
|
-
"@symbiote-native/
|
|
139
|
-
"@symbiote-native/solid": "3.0
|
|
140
|
-
"@symbiote-native/test-utils": "0.4.
|
|
141
|
-
"@symbiote-native/vue": "3.0
|
|
135
|
+
"@symbiote-native/engine": "1.5.0",
|
|
136
|
+
"@symbiote-native/react": "3.2.0",
|
|
137
|
+
"@symbiote-native/svelte": "3.1.0",
|
|
138
|
+
"@symbiote-native/angular": "3.2.0",
|
|
139
|
+
"@symbiote-native/solid": "3.1.0",
|
|
140
|
+
"@symbiote-native/test-utils": "0.4.6",
|
|
141
|
+
"@symbiote-native/vue": "3.2.0"
|
|
142
142
|
},
|
|
143
143
|
"scripts": {
|
|
144
144
|
"typecheck": "tsc --build",
|
package/src/angular/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
export { PermissionsService } from './services/permissions.service';
|
|
1
|
+
// @symbiote-native/tracking-transparency/angular: the core plus `TrackingPermissionsService`
|
|
2
|
+
export { TrackingPermissionsService } from './tracking-permissions.service';
|
|
4
3
|
export * from '../core';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Angular twin of `../react`'s `useTrackingPermissions`: `inject(...).connect()` gives a signal
|
|
2
|
+
|
|
3
|
+
import { Injectable } from '@angular/core';
|
|
4
|
+
import { PermissionsServiceBase } from '@symbiote-native/angular';
|
|
5
|
+
import { trackingPermissionMethods } from '../core/tracking-permission-api';
|
|
6
|
+
import type { PermissionResponse } from '../core';
|
|
7
|
+
|
|
8
|
+
@Injectable({ providedIn: 'root' })
|
|
9
|
+
export class TrackingPermissionsService extends PermissionsServiceBase<PermissionResponse> {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(
|
|
12
|
+
trackingPermissionMethods.getMethod,
|
|
13
|
+
trackingPermissionMethods.requestMethod,
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// `methods` every adapter's `useTrackingPermissions` binds to the shared
|
|
2
|
+
// `@symbiote-native/{react,vue,solid,svelte}` `createPermissionHook` factory
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
getTrackingPermissionsAsync,
|
|
6
|
+
requestTrackingPermissionsAsync,
|
|
7
|
+
} from './tracking-transparency';
|
|
8
|
+
|
|
9
|
+
export const trackingPermissionMethods = {
|
|
10
|
+
getMethod: getTrackingPermissionsAsync,
|
|
11
|
+
requestMethod: requestTrackingPermissionsAsync,
|
|
12
|
+
};
|
package/src/react/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
// @symbiote-native/tracking-transparency/react: the
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export { usePermissions } from './hooks/use-permissions';
|
|
1
|
+
// @symbiote-native/tracking-transparency/react: the core plus `useTrackingPermissions`
|
|
2
|
+
export {
|
|
3
|
+
useTrackingPermissions,
|
|
4
|
+
type IUseTrackingPermissionsHook,
|
|
5
|
+
} from './use-tracking-permissions';
|
|
7
6
|
export * from '../core';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createPermissionHook } from '@symbiote-native/react';
|
|
2
|
+
import { trackingPermissionMethods } from '../core/tracking-permission-api';
|
|
3
|
+
import type { PermissionResponse } from '../core';
|
|
4
|
+
import type { IPermissionHookBehavior } from '@symbiote-native/engine';
|
|
5
|
+
|
|
6
|
+
export type IUseTrackingPermissionsHook = (
|
|
7
|
+
options?: IPermissionHookBehavior,
|
|
8
|
+
) => [
|
|
9
|
+
PermissionResponse | null,
|
|
10
|
+
() => Promise<PermissionResponse>,
|
|
11
|
+
() => Promise<PermissionResponse>,
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
// React twin of `expo-tracking-transparency`'s `useTrackingPermissions`
|
|
15
|
+
export const useTrackingPermissions: IUseTrackingPermissionsHook =
|
|
16
|
+
createPermissionHook(trackingPermissionMethods);
|
package/src/solid/index.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
// @symbiote-native/tracking-transparency/solid: the
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export { createPermissions } from './primitives/create-permissions';
|
|
1
|
+
// @symbiote-native/tracking-transparency/solid: the core plus `useTrackingPermissions`
|
|
2
|
+
export {
|
|
3
|
+
useTrackingPermissions,
|
|
4
|
+
type IUseTrackingPermissionsHook,
|
|
5
|
+
} from './use-tracking-permissions';
|
|
8
6
|
export * from '../core';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createPermissionHook } from '@symbiote-native/solid';
|
|
2
|
+
import { trackingPermissionMethods } from '../core/tracking-permission-api';
|
|
3
|
+
import type { PermissionResponse } from '../core';
|
|
4
|
+
import type { IPermissionHookBehavior } from '@symbiote-native/engine';
|
|
5
|
+
import type { Accessor } from 'solid-js';
|
|
6
|
+
|
|
7
|
+
export type IUseTrackingPermissionsHook = (
|
|
8
|
+
options?: IPermissionHookBehavior,
|
|
9
|
+
) => [
|
|
10
|
+
Accessor<PermissionResponse | null>,
|
|
11
|
+
() => Promise<PermissionResponse>,
|
|
12
|
+
() => Promise<PermissionResponse>,
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
// Solid twin of `../react`'s `useTrackingPermissions`
|
|
16
|
+
export const useTrackingPermissions: IUseTrackingPermissionsHook =
|
|
17
|
+
createPermissionHook(trackingPermissionMethods);
|
package/src/svelte/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
// @symbiote-native/tracking-transparency/svelte: the
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export { usePermissions } from './runes/use-permissions.svelte';
|
|
1
|
+
// @symbiote-native/tracking-transparency/svelte: the core plus `useTrackingPermissions`
|
|
2
|
+
export {
|
|
3
|
+
useTrackingPermissions,
|
|
4
|
+
type IUseTrackingPermissionsHook,
|
|
5
|
+
} from './use-tracking-permissions.svelte';
|
|
7
6
|
export * from '../core';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createPermissionHook } from '@symbiote-native/svelte/runes/create-permission-hook';
|
|
2
|
+
import { trackingPermissionMethods } from '../core/tracking-permission-api';
|
|
3
|
+
import type { PermissionResponse } from '../core';
|
|
4
|
+
import type { IPermissionHookBehavior } from '@symbiote-native/engine';
|
|
5
|
+
|
|
6
|
+
export type IUseTrackingPermissionsHook = (
|
|
7
|
+
options?: IPermissionHookBehavior,
|
|
8
|
+
) => {
|
|
9
|
+
readonly status: PermissionResponse | null;
|
|
10
|
+
requestPermission: () => Promise<PermissionResponse>;
|
|
11
|
+
getPermission: () => Promise<PermissionResponse>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// Svelte twin of `../react`'s `useTrackingPermissions`
|
|
15
|
+
export const useTrackingPermissions: IUseTrackingPermissionsHook =
|
|
16
|
+
createPermissionHook(trackingPermissionMethods);
|
package/src/vue/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
// @symbiote-native/tracking-transparency/vue: the
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export { usePermissions } from './composables/use-permissions';
|
|
1
|
+
// @symbiote-native/tracking-transparency/vue: the core plus `useTrackingPermissions`
|
|
2
|
+
export {
|
|
3
|
+
useTrackingPermissions,
|
|
4
|
+
type IUseTrackingPermissionsHook,
|
|
5
|
+
} from './use-tracking-permissions';
|
|
7
6
|
export * from '../core';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createPermissionHook } from '@symbiote-native/vue';
|
|
2
|
+
import { trackingPermissionMethods } from '../core/tracking-permission-api';
|
|
3
|
+
import type { PermissionResponse } from '../core';
|
|
4
|
+
import type { IPermissionHookBehavior } from '@symbiote-native/engine';
|
|
5
|
+
import type { Ref } from '@vue/runtime-core';
|
|
6
|
+
|
|
7
|
+
export type IUseTrackingPermissionsHook = (
|
|
8
|
+
options?: IPermissionHookBehavior,
|
|
9
|
+
) => [
|
|
10
|
+
Ref<PermissionResponse | null>,
|
|
11
|
+
() => Promise<PermissionResponse>,
|
|
12
|
+
() => Promise<PermissionResponse>,
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
// Vue twin of `../react`'s `useTrackingPermissions`
|
|
16
|
+
export const useTrackingPermissions: IUseTrackingPermissionsHook =
|
|
17
|
+
createPermissionHook(trackingPermissionMethods);
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type Signal } from '@angular/core';
|
|
2
|
-
import { type PermissionResponse } from '../../../core';
|
|
3
|
-
export declare class PermissionsService {
|
|
4
|
-
private readonly status;
|
|
5
|
-
private readonly fetchError;
|
|
6
|
-
private isAutoFetchStarted;
|
|
7
|
-
/** Why the auto-fetch left `status` at null. Cleared by the next successful get()/request(). */
|
|
8
|
-
readonly error: Signal<Error | null>;
|
|
9
|
-
connect(): Signal<PermissionResponse | null>;
|
|
10
|
-
get(): Promise<PermissionResponse>;
|
|
11
|
-
request(): Promise<PermissionResponse>;
|
|
12
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// React lifecycle wiring over the framework-agnostic core (core/tracking-transparency.ts) —
|
|
2
|
-
// auto-fetches the current permission status on mount, then exposes get/request as imperative
|
|
3
|
-
// callbacks. Mirrors the shape @symbiote-native/cellular's own usePermissions ships in parallel,
|
|
4
|
-
// so both stay byte-for-byte consistent.
|
|
5
|
-
//
|
|
6
|
-
// The mount fetch has nobody to reject to, so its failure lands in the 4th tuple slot (`error`)
|
|
7
|
-
// instead of escaping as an unhandled rejection: a null status with a non-null error is how a
|
|
8
|
-
// consumer tells "the fetch failed" from "not fetched yet". get()/request() still reject to their
|
|
9
|
-
// direct caller — only the automatic call is made safe.
|
|
10
|
-
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
11
|
-
import { getTrackingPermissionsAsync, requestTrackingPermissionsAsync, } from '../../../core/index.js';
|
|
12
|
-
export function usePermissions() {
|
|
13
|
-
const isMounted = useRef(true);
|
|
14
|
-
const [status, setStatus] = useState(null);
|
|
15
|
-
const [error, setError] = useState(null);
|
|
16
|
-
const getPermission = useCallback(async () => {
|
|
17
|
-
const response = await getTrackingPermissionsAsync();
|
|
18
|
-
if (isMounted.current) {
|
|
19
|
-
setStatus(response);
|
|
20
|
-
setError(null);
|
|
21
|
-
}
|
|
22
|
-
return response;
|
|
23
|
-
}, []);
|
|
24
|
-
const requestPermission = useCallback(async () => {
|
|
25
|
-
const response = await requestTrackingPermissionsAsync();
|
|
26
|
-
if (isMounted.current) {
|
|
27
|
-
setStatus(response);
|
|
28
|
-
setError(null);
|
|
29
|
-
}
|
|
30
|
-
return response;
|
|
31
|
-
}, []);
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
isMounted.current = true;
|
|
34
|
-
getPermission().catch((cause) => {
|
|
35
|
-
if (isMounted.current)
|
|
36
|
-
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
37
|
-
});
|
|
38
|
-
return () => {
|
|
39
|
-
isMounted.current = false;
|
|
40
|
-
};
|
|
41
|
-
}, [getPermission]);
|
|
42
|
-
return [status, requestPermission, getPermission, error];
|
|
43
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type Accessor } from 'solid-js';
|
|
2
|
-
import { type PermissionResponse } from '../../core';
|
|
3
|
-
export declare function createPermissions(): {
|
|
4
|
-
status: Accessor<PermissionResponse | null>;
|
|
5
|
-
error: Accessor<Error | null>;
|
|
6
|
-
request: () => Promise<PermissionResponse>;
|
|
7
|
-
get: () => Promise<PermissionResponse>;
|
|
8
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// createPermissions — the Solid twin of React's `usePermissions` hook, Vue's composable and
|
|
2
|
-
// Svelte's rune, over the framework-agnostic core (core/tracking-transparency.ts). Auto-fetches
|
|
3
|
-
// the current permission status, then exposes get/request as imperative callbacks.
|
|
4
|
-
//
|
|
5
|
-
// `primitives/` and `create*`, never `hooks/`+`use*`: Solid's ecosystem calls a composable
|
|
6
|
-
// reactive function a PRIMITIVE and reserves `use*` for consuming something that already exists.
|
|
7
|
-
// Full rationale in adapters/solid/src/primitives/create-color-scheme.ts.
|
|
8
|
-
//
|
|
9
|
-
// Returns ACCESSORS, never snapshots: a Solid component body runs ONCE, so returned values would
|
|
10
|
-
// pin the caller to the null pre-fetch state forever.
|
|
11
|
-
//
|
|
12
|
-
// The auto-fetch fires from the primitive body rather than a mount effect — the shape
|
|
13
|
-
// `createResource` uses, and the reason this primitive needs no lifecycle hook at all. Its failure
|
|
14
|
-
// lands in `error` instead of escaping as an unhandled rejection: a null status with a non-null
|
|
15
|
-
// error is how a consumer tells "the fetch failed" from "not fetched yet". get()/request() still
|
|
16
|
-
// reject to their direct caller — only the automatic call is made safe.
|
|
17
|
-
//
|
|
18
|
-
// No isMounted guard around the late write, unlike React's hook: once the owning root is disposed
|
|
19
|
-
// nothing is subscribed to these signals any more, so a resolution arriving afterwards is inert.
|
|
20
|
-
import { createSignal } from 'solid-js';
|
|
21
|
-
import { getTrackingPermissionsAsync, requestTrackingPermissionsAsync, } from '../../core/index.js';
|
|
22
|
-
export function createPermissions() {
|
|
23
|
-
const [status, setStatus] = createSignal(null);
|
|
24
|
-
const [error, setError] = createSignal(null);
|
|
25
|
-
const get = async () => {
|
|
26
|
-
const response = await getTrackingPermissionsAsync();
|
|
27
|
-
setStatus(response);
|
|
28
|
-
setError(null);
|
|
29
|
-
return response;
|
|
30
|
-
};
|
|
31
|
-
const request = async () => {
|
|
32
|
-
const response = await requestTrackingPermissionsAsync();
|
|
33
|
-
setStatus(response);
|
|
34
|
-
setError(null);
|
|
35
|
-
return response;
|
|
36
|
-
};
|
|
37
|
-
get().catch((cause) => {
|
|
38
|
-
setError(cause instanceof Error ? cause : new Error(String(cause)));
|
|
39
|
-
});
|
|
40
|
-
return { status, error, request, get };
|
|
41
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type PermissionResponse } from '../../core';
|
|
2
|
-
export declare function usePermissions(): {
|
|
3
|
-
readonly status: PermissionResponse | null;
|
|
4
|
-
readonly error: Error | null;
|
|
5
|
-
request: () => Promise<PermissionResponse>;
|
|
6
|
-
get: () => Promise<PermissionResponse>;
|
|
7
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// Svelte lifecycle wiring over the framework-agnostic core (core/tracking-transparency.ts) —
|
|
2
|
-
// auto-fetches the current permission status on mount, then exposes get/request as imperative
|
|
3
|
-
// callbacks. Just a one-shot get with no ongoing subscription, so `$effect` needs no cleanup.
|
|
4
|
-
//
|
|
5
|
-
// `.svelte.ts` (not `.ts`): runes ($state/$effect) only work in files with this extension
|
|
6
|
-
// outside an actual `.svelte` component. `status` is returned as a getter, NOT a bare
|
|
7
|
-
// `$state`: Svelte 5 reactivity is lexically scoped to the declaring module and doesn't
|
|
8
|
-
// survive being returned as a raw value from a plain function — mirrors how Vue's `Ref`
|
|
9
|
-
// needs `.value` to unwrap.
|
|
10
|
-
//
|
|
11
|
-
// The mount fetch has nobody to reject to, so its failure lands in `error` (a second boxed getter,
|
|
12
|
-
// same reason as `status`) instead of escaping as an unhandled rejection: a null status with a
|
|
13
|
-
// non-null error is how a consumer tells "the fetch failed" from "not fetched yet".
|
|
14
|
-
// get()/request() still reject to their direct caller — only the automatic call is made safe.
|
|
15
|
-
import { getTrackingPermissionsAsync, requestTrackingPermissionsAsync, } from '../../core/index.js';
|
|
16
|
-
export function usePermissions() {
|
|
17
|
-
let status = $state(null);
|
|
18
|
-
let error = $state(null);
|
|
19
|
-
const get = async () => {
|
|
20
|
-
const response = await getTrackingPermissionsAsync();
|
|
21
|
-
status = response;
|
|
22
|
-
error = null;
|
|
23
|
-
return response;
|
|
24
|
-
};
|
|
25
|
-
const request = async () => {
|
|
26
|
-
const response = await requestTrackingPermissionsAsync();
|
|
27
|
-
status = response;
|
|
28
|
-
error = null;
|
|
29
|
-
return response;
|
|
30
|
-
};
|
|
31
|
-
$effect(() => {
|
|
32
|
-
// `get` is a plain closure, not reactive state, so the effect has an empty dependency set and
|
|
33
|
-
// runs exactly once on mount — the twin of Vue's onMounted. The catch runs after the effect
|
|
34
|
-
// has settled, so writing `error` there adds no dependency and does not re-arm it.
|
|
35
|
-
get().catch((cause) => {
|
|
36
|
-
error = cause instanceof Error ? cause : new Error(String(cause));
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
return {
|
|
40
|
-
get status() {
|
|
41
|
-
return status;
|
|
42
|
-
},
|
|
43
|
-
get error() {
|
|
44
|
-
return error;
|
|
45
|
-
},
|
|
46
|
-
request,
|
|
47
|
-
get,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type Ref } from '@vue/runtime-core';
|
|
2
|
-
import { type PermissionResponse } from '../../../core';
|
|
3
|
-
export declare function usePermissions(): {
|
|
4
|
-
status: Ref<PermissionResponse | null>;
|
|
5
|
-
error: Ref<Error | null>;
|
|
6
|
-
request: () => Promise<PermissionResponse>;
|
|
7
|
-
get: () => Promise<PermissionResponse>;
|
|
8
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// Vue lifecycle wiring over the framework-agnostic core (core/tracking-transparency.ts) —
|
|
2
|
-
// auto-fetches the current permission status on mount (mirrors use-battery-level's
|
|
3
|
-
// onMounted/onUnmounted style, but there is no ongoing subscription to tear down here, just a
|
|
4
|
-
// one-shot get), then exposes get/request as imperative callbacks.
|
|
5
|
-
//
|
|
6
|
-
// The mount fetch has nobody to reject to, so its failure lands in the `error` ref instead of
|
|
7
|
-
// escaping as an unhandled rejection: a null status with a non-null error is how a consumer tells
|
|
8
|
-
// "the fetch failed" from "not fetched yet". get()/request() still reject to their direct caller —
|
|
9
|
-
// only the automatic call is made safe.
|
|
10
|
-
import { onMounted, ref } from '@vue/runtime-core';
|
|
11
|
-
import { getTrackingPermissionsAsync, requestTrackingPermissionsAsync, } from '../../../core/index.js';
|
|
12
|
-
export function usePermissions() {
|
|
13
|
-
const status = ref(null);
|
|
14
|
-
const error = ref(null);
|
|
15
|
-
const get = async () => {
|
|
16
|
-
const response = await getTrackingPermissionsAsync();
|
|
17
|
-
status.value = response;
|
|
18
|
-
error.value = null;
|
|
19
|
-
return response;
|
|
20
|
-
};
|
|
21
|
-
const request = async () => {
|
|
22
|
-
const response = await requestTrackingPermissionsAsync();
|
|
23
|
-
status.value = response;
|
|
24
|
-
error.value = null;
|
|
25
|
-
return response;
|
|
26
|
-
};
|
|
27
|
-
onMounted(() => {
|
|
28
|
-
get().catch((cause) => {
|
|
29
|
-
error.value = cause instanceof Error ? cause : new Error(String(cause));
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
return { status, error, request, get };
|
|
33
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { type Signal } from '@angular/core';
|
|
2
|
-
import { type PermissionResponse } from '../../../core';
|
|
3
|
-
import * as i0 from "@angular/core";
|
|
4
|
-
export declare class PermissionsService {
|
|
5
|
-
private readonly status;
|
|
6
|
-
private readonly fetchError;
|
|
7
|
-
private isAutoFetchStarted;
|
|
8
|
-
/** Why the auto-fetch left `status` at null. Cleared by the next successful get()/request(). */
|
|
9
|
-
readonly error: Signal<Error | null>;
|
|
10
|
-
connect(): Signal<PermissionResponse | null>;
|
|
11
|
-
get(): Promise<PermissionResponse>;
|
|
12
|
-
request(): Promise<PermissionResponse>;
|
|
13
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<PermissionsService, never>;
|
|
14
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<PermissionsService>;
|
|
15
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// Angular twin of React's usePermissions hook and Vue's usePermissions composable.
|
|
2
|
-
// `connect()` auto-fetches once (no ongoing subscription to clean up, so no Injector/effect
|
|
3
|
-
// needed, unlike BatteryStateService) and returns a readonly signal; get()/request() are
|
|
4
|
-
// imperative one-shot methods.
|
|
5
|
-
//
|
|
6
|
-
// readonly status = inject(PermissionsService).connect();
|
|
7
|
-
// // template: {{ status()?.granted }}
|
|
8
|
-
//
|
|
9
|
-
// The auto-fetch has nobody to reject to, so its failure lands in the `error` signal instead of
|
|
10
|
-
// escaping as an unhandled rejection: a null status with a non-null error is how a consumer tells
|
|
11
|
-
// "the fetch failed" from "not fetched yet". get()/request() still reject to their direct caller —
|
|
12
|
-
// only the automatic call is made safe.
|
|
13
|
-
import { Injectable, signal } from '@angular/core';
|
|
14
|
-
import { getTrackingPermissionsAsync, requestTrackingPermissionsAsync, } from '../../../core';
|
|
15
|
-
import * as i0 from "@angular/core";
|
|
16
|
-
export class PermissionsService {
|
|
17
|
-
status = signal(null, /* @ts-ignore */
|
|
18
|
-
...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
19
|
-
fetchError = signal(null, /* @ts-ignore */
|
|
20
|
-
...(ngDevMode ? [{ debugName: "fetchError" }] : /* istanbul ignore next */ []));
|
|
21
|
-
isAutoFetchStarted = false;
|
|
22
|
-
/** Why the auto-fetch left `status` at null. Cleared by the next successful get()/request(). */
|
|
23
|
-
error = this.fetchError.asReadonly();
|
|
24
|
-
connect() {
|
|
25
|
-
// Latched rather than guarded on `status() === null`: a failed fetch leaves status null
|
|
26
|
-
// forever, so the old guard turned every later connect() into another native call — unbounded
|
|
27
|
-
// once connect() is reached from a change-detected expression instead of a field initializer.
|
|
28
|
-
if (!this.isAutoFetchStarted) {
|
|
29
|
-
this.isAutoFetchStarted = true;
|
|
30
|
-
this.get().catch((cause) => {
|
|
31
|
-
this.fetchError.set(cause instanceof Error ? cause : new Error(String(cause)));
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
return this.status.asReadonly();
|
|
35
|
-
}
|
|
36
|
-
async get() {
|
|
37
|
-
const response = await getTrackingPermissionsAsync();
|
|
38
|
-
this.status.set(response);
|
|
39
|
-
this.fetchError.set(null);
|
|
40
|
-
return response;
|
|
41
|
-
}
|
|
42
|
-
async request() {
|
|
43
|
-
const response = await requestTrackingPermissionsAsync();
|
|
44
|
-
this.status.set(response);
|
|
45
|
-
this.fetchError.set(null);
|
|
46
|
-
return response;
|
|
47
|
-
}
|
|
48
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PermissionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
49
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PermissionsService, providedIn: 'root' });
|
|
50
|
-
}
|
|
51
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PermissionsService, decorators: [{
|
|
52
|
-
type: Injectable,
|
|
53
|
-
args: [{ providedIn: 'root' }]
|
|
54
|
-
}] });
|
|
55
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/angular/services/permissions.service/index.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,4FAA4F;AAC5F,yFAAyF;AACzF,+BAA+B;AAC/B,EAAE;AACF,4DAA4D;AAC5D,yCAAyC;AACzC,EAAE;AACF,gGAAgG;AAChG,kGAAkG;AAClG,mGAAmG;AACnG,wCAAwC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AAChE,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,GAEhC,MAAM,eAAe,CAAC;;AAGvB,MAAM,OAAO,kBAAkB;IACZ,MAAM,GAAG,MAAM,CAA4B,IAAI;+EAAC,CAAC;IACjD,UAAU,GAAG,MAAM,CAAe,IAAI;mFAAC,CAAC;IACjD,kBAAkB,GAAG,KAAK,CAAC;IAEnC,gGAAgG;IACvF,KAAK,GAAyB,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;IAEpE,OAAO;QACL,wFAAwF;QACxF,8FAA8F;QAC9F,8FAA8F;QAC9F,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC7B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAC/B,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBAClC,IAAI,CAAC,UAAU,CAAC,GAAG,CACjB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,GAAG;QACP,MAAM,QAAQ,GAAG,MAAM,2BAA2B,EAAE,CAAC;QACrD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,QAAQ,GAAG,MAAM,+BAA+B,EAAE,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,OAAO,QAAQ,CAAC;IAClB,CAAC;uGAnCU,kBAAkB;2GAAlB,kBAAkB,cADL,MAAM;;2FACnB,kBAAkB;kBAD9B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// Angular twin of React's usePermissions hook and Vue's usePermissions composable.
|
|
2
|
-
// `connect()` auto-fetches once (no ongoing subscription to clean up, so no Injector/effect
|
|
3
|
-
// needed, unlike BatteryStateService) and returns a readonly signal; get()/request() are
|
|
4
|
-
// imperative one-shot methods.
|
|
5
|
-
//
|
|
6
|
-
// readonly status = inject(PermissionsService).connect();
|
|
7
|
-
// // template: {{ status()?.granted }}
|
|
8
|
-
//
|
|
9
|
-
// The auto-fetch has nobody to reject to, so its failure lands in the `error` signal instead of
|
|
10
|
-
// escaping as an unhandled rejection: a null status with a non-null error is how a consumer tells
|
|
11
|
-
// "the fetch failed" from "not fetched yet". get()/request() still reject to their direct caller —
|
|
12
|
-
// only the automatic call is made safe.
|
|
13
|
-
import { Injectable, signal, type Signal } from '@angular/core';
|
|
14
|
-
import {
|
|
15
|
-
getTrackingPermissionsAsync,
|
|
16
|
-
requestTrackingPermissionsAsync,
|
|
17
|
-
type PermissionResponse,
|
|
18
|
-
} from '../../../core';
|
|
19
|
-
|
|
20
|
-
@Injectable({ providedIn: 'root' })
|
|
21
|
-
export class PermissionsService {
|
|
22
|
-
private readonly status = signal<PermissionResponse | null>(null);
|
|
23
|
-
private readonly fetchError = signal<Error | null>(null);
|
|
24
|
-
private isAutoFetchStarted = false;
|
|
25
|
-
|
|
26
|
-
/** Why the auto-fetch left `status` at null. Cleared by the next successful get()/request(). */
|
|
27
|
-
readonly error: Signal<Error | null> = this.fetchError.asReadonly();
|
|
28
|
-
|
|
29
|
-
connect(): Signal<PermissionResponse | null> {
|
|
30
|
-
// Latched rather than guarded on `status() === null`: a failed fetch leaves status null
|
|
31
|
-
// forever, so the old guard turned every later connect() into another native call — unbounded
|
|
32
|
-
// once connect() is reached from a change-detected expression instead of a field initializer.
|
|
33
|
-
if (!this.isAutoFetchStarted) {
|
|
34
|
-
this.isAutoFetchStarted = true;
|
|
35
|
-
this.get().catch((cause: unknown) => {
|
|
36
|
-
this.fetchError.set(
|
|
37
|
-
cause instanceof Error ? cause : new Error(String(cause)),
|
|
38
|
-
);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
return this.status.asReadonly();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async get(): Promise<PermissionResponse> {
|
|
45
|
-
const response = await getTrackingPermissionsAsync();
|
|
46
|
-
this.status.set(response);
|
|
47
|
-
this.fetchError.set(null);
|
|
48
|
-
return response;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async request(): Promise<PermissionResponse> {
|
|
52
|
-
const response = await requestTrackingPermissionsAsync();
|
|
53
|
-
this.status.set(response);
|
|
54
|
-
this.fetchError.set(null);
|
|
55
|
-
return response;
|
|
56
|
-
}
|
|
57
|
-
}
|