Summary
Extract a framework-agnostic client core so new SDKs (Vue, Angular, and similar) are thin bindings over one shared implementation instead of parallel reimplementations.
This issue has been re-scoped after review. The actionable near-term pieces were split into #76, #77, and #78. What remains here is the deferred extraction itself.
Key correction: the client is not the hard part
The obvious assumption is that the shared core is the HTTP client. It is not. These modules already have zero React imports and are effectively extraction-ready today:
src/client/createSeamlessAuthClient.ts
src/client/webauthnPrf.ts
src/client/webauthnSupport.ts
src/fetchWithAuth.ts
src/scopedRoles.ts
src/types.ts
The part that will actually be duplicated is the session state machine in src/AuthProvider.tsx: loading state, user, credentials, organizations, active organization, step-up status, validateToken, logout-on-401, markSignedIn, and refresh-after-mutation. That logic is React-only today. If a Vue composable and an Angular service each reimplement it, they will drift, and they will drift on auth state, which is the worst place for divergence.
So the core should expose a framework-agnostic session store (getState, subscribe, and actions), not just a fetch client. Each adapter then becomes a thin binding:
- React:
useSyncExternalStore
- Vue: a composable or Pinia store
- Angular: an injectable service exposing an observable
That reframes this work from moving files to extracting a state machine, which is the part that needs real design.
Naming constraints
@seamless-auth/core is already taken by the server monorepo (seamless-auth-server/packages/core), so it is not available for a client core.
@seamless-auth/types already exists as a separate package that this repo does not currently consume. Decide how it relates before introducing a third naming lane.
- Suggested name:
@seamless-auth/client.
Prerequisites
Timing
Do this as step one of the first non-React adapter (Vue or Angular), not as a speculative refactor. Extracting earlier costs a repo restructure, dual publishing, changesets reconfiguration, and a consumer migration, in exchange for benefits that cannot be collected until a second SDK exists.
Next.js (#78) explicitly does not depend on this work, because Next.js is React and needs SSR safety rather than a new binding.
Cross-repo note
The conformance harness in seamless-cli takes per-repo refs (react-ref, templates-ref, and similar). Each new adapter will need a ref and a lane there, so the harness needs generalizing as adapters are added. That work lives in seamless-cli, not this repo.
Related
Summary
Extract a framework-agnostic client core so new SDKs (Vue, Angular, and similar) are thin bindings over one shared implementation instead of parallel reimplementations.
This issue has been re-scoped after review. The actionable near-term pieces were split into #76, #77, and #78. What remains here is the deferred extraction itself.
Key correction: the client is not the hard part
The obvious assumption is that the shared core is the HTTP client. It is not. These modules already have zero React imports and are effectively extraction-ready today:
src/client/createSeamlessAuthClient.tssrc/client/webauthnPrf.tssrc/client/webauthnSupport.tssrc/fetchWithAuth.tssrc/scopedRoles.tssrc/types.tsThe part that will actually be duplicated is the session state machine in
src/AuthProvider.tsx: loading state, user, credentials, organizations, active organization, step-up status,validateToken, logout-on-401,markSignedIn, and refresh-after-mutation. That logic is React-only today. If a Vue composable and an Angular service each reimplement it, they will drift, and they will drift on auth state, which is the worst place for divergence.So the core should expose a framework-agnostic session store (
getState,subscribe, and actions), not just a fetch client. Each adapter then becomes a thin binding:useSyncExternalStoreThat reframes this work from moving files to extracting a state machine, which is the part that needs real design.
Naming constraints
@seamless-auth/coreis already taken by the server monorepo (seamless-auth-server/packages/core), so it is not available for a client core.@seamless-auth/typesalready exists as a separate package that this repo does not currently consume. Decide how it relates before introducing a third naming lane.@seamless-auth/client.Prerequisites
Response, others return parsed result objects). With one SDK this is a wart. With four, each adapter bakes in its own error-handling convention and they will disagree. Settle this before the extraction, not after.Timing
Do this as step one of the first non-React adapter (Vue or Angular), not as a speculative refactor. Extracting earlier costs a repo restructure, dual publishing, changesets reconfiguration, and a consumer migration, in exchange for benefits that cannot be collected until a second SDK exists.
Next.js (#78) explicitly does not depend on this work, because Next.js is React and needs SSR safety rather than a new binding.
Cross-repo note
The conformance harness in
seamless-clitakes per-repo refs (react-ref,templates-ref, and similar). Each new adapter will need a ref and a lane there, so the harness needs generalizing as adapters are added. That work lives inseamless-cli, not this repo.Related