{{ banner }}
+ +``` diff --git a/packages/vue/package.json b/packages/vue/package.json new file mode 100644 index 00000000..cbf02298 --- /dev/null +++ b/packages/vue/package.json @@ -0,0 +1,54 @@ +{ + "name": "@tryabby/vue", + "version": "7.0.1", + "description": "Vue 3 integration for Abby - A/B Testing & Feature Flags", + "main": "dist/index.js", + "files": ["dist"], + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + } + }, + "scripts": { + "build": "tsup src/", + "dev": "pnpm run build --watch", + "test": "vitest" + }, + "homepage": "https://docs.tryabby.com", + "keywords": [ + "vue", + "vue3", + "nuxt", + "ab-testing", + "feature-flags", + "tryabby", + "remote-config" + ], + "author": "", + "license": "ISC", + "devDependencies": { + "@tryabby/devtools": "workspace:*", + "@types/js-cookie": "^3.0.3", + "@vue/test-utils": "^2.4.6", + "jsdom": "^20.0.3", + "msw": "^0.49.1", + "node-fetch": "^3.3.0", + "tsconfig": "workspace:*", + "tsup": "^6.5.0", + "typescript": "5.5.4", + "vite": "5.4.0", + "vitest": "2.0.5", + "vue": "^3.4.38" + }, + "peerDependencies": { + "vue": "^3.3.0 || ^3.4.0 || ^3.5.0" + }, + "dependencies": { + "@tryabby/core": "workspace:*", + "js-cookie": "^3.0.1" + } +} diff --git a/packages/vue/src/StorageService.ts b/packages/vue/src/StorageService.ts new file mode 100644 index 00000000..7633105e --- /dev/null +++ b/packages/vue/src/StorageService.ts @@ -0,0 +1,76 @@ +import { + type IStorageService, + type StorageServiceOptions, + getABStorageKey, + getFFStorageKey, + getRCStorageKey, +} from "@tryabby/core"; +import Cookie from "js-cookie"; + +const DEFAULT_COOKIE_AGE = 365; + +class ABStorageService implements IStorageService { + get(projectId: string, testName: string): string | null { + const retrievedValue = Cookie.get(getABStorageKey(projectId, testName)); + if (!retrievedValue) return null; + + return retrievedValue; + } + + set( + projectId: string, + testName: string, + value: string, + options?: StorageServiceOptions + ): void { + Cookie.set(getABStorageKey(projectId, testName), value, { + expires: options?.expiresInDays + ? options.expiresInDays + : DEFAULT_COOKIE_AGE, + }); + } + + remove(projectId: string, testName: string): void { + Cookie.remove(getABStorageKey(projectId, testName)); + } +} + +class FFStorageService implements IStorageService { + get(projectId: string, flagName: string): string | null { + const retrievedValue = Cookie.get(getFFStorageKey(projectId, flagName)); + if (!retrievedValue) return null; + + return retrievedValue; + } + + set(projectId: string, flagName: string, value: string): void { + Cookie.set(getFFStorageKey(projectId, flagName), value, { + expires: DEFAULT_COOKIE_AGE, + }); + } + + remove(projectId: string, flagName: string): void { + Cookie.remove(getFFStorageKey(projectId, flagName)); + } +} + +class RCStorageService implements IStorageService { + get(projectId: string, key: string): string | null { + const retrievedValue = Cookie.get(getRCStorageKey(projectId, key)); + return retrievedValue ?? null; + } + + set(projectId: string, key: string, value: string): void { + Cookie.set(getRCStorageKey(projectId, key), value, { + expires: DEFAULT_COOKIE_AGE, + }); + } + + remove(projectId: string, key: string): void { + Cookie.remove(getRCStorageKey(projectId, key)); + } +} + +export const TestStorageService = new ABStorageService(); +export const FlagStorageService = new FFStorageService(); +export const RemoteConfigStorageService = new RCStorageService(); diff --git a/packages/vue/src/context.ts b/packages/vue/src/context.ts new file mode 100644 index 00000000..5e291629 --- /dev/null +++ b/packages/vue/src/context.ts @@ -0,0 +1,351 @@ +import { + type ABConfig, + Abby, + type AbbyConfig, + type AbbyDataResponse, + AbbyEventType, + HttpService, + type RemoteConfigValueString, + type RemoteConfigValueStringToType, + type ValidatorType, +} from "@tryabby/core"; +import type { Infer } from "@tryabby/core/validation"; +import type { AbbyDevtoolProps, DevtoolsFactory } from "@tryabby/devtools"; +import { + type App, + type ComputedRef, + type InjectionKey, + type Plugin, + type PropType, + computed, + defineComponent, + onMounted, + onUnmounted, + provide, + shallowRef, +} from "vue"; +import { + FlagStorageService, + RemoteConfigStorageService, + TestStorageService, +} from "./StorageService"; + +export type withDevtoolsFunction = ( + factory: DevtoolsFactory, + props: Omit