@instantdb/svelte 0.0.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.
@@ -0,0 +1,149 @@
1
+ <script lang="ts" generics="RoomSchema extends RoomSchemaShape, RoomType extends string & keyof RoomSchema">
2
+ import type { RoomSchemaShape } from '@instantdb/core';
3
+ import type { InstantSvelteRoom } from './InstantSvelteRoom.svelte.js';
4
+ import { usePresence } from './InstantSvelteRoom.svelte.js';
5
+ import type { Snippet } from 'svelte';
6
+
7
+ let {
8
+ room,
9
+ spaceId: _spaceId,
10
+ as = 'div',
11
+ className,
12
+ style,
13
+ userCursorColor,
14
+ children,
15
+ renderCursor,
16
+ propagate,
17
+ zIndex,
18
+ }: {
19
+ room: InstantSvelteRoom<any, RoomSchema, RoomType>;
20
+ spaceId?: string;
21
+ as?: string;
22
+ className?: string;
23
+ style?: string;
24
+ userCursorColor?: string;
25
+ children?: Snippet;
26
+ renderCursor?: Snippet<[{ color: string; presence: RoomSchema[RoomType]['presence'] }]>;
27
+ propagate?: boolean;
28
+ zIndex?: number;
29
+ } = $props();
30
+
31
+ const spaceId = _spaceId || `cursors-space-default--${String(room.type)}-${room.id}`;
32
+
33
+ const cursorsPresence = usePresence(room, {
34
+ keys: [spaceId] as (keyof RoomSchema[RoomType]['presence'])[],
35
+ });
36
+
37
+ function publishCursor(rect: DOMRect, touch: { clientX: number; clientY: number }) {
38
+ const x = touch.clientX;
39
+ const y = touch.clientY;
40
+ const xPercent = ((x - rect.left) / rect.width) * 100;
41
+ const yPercent = ((y - rect.top) / rect.height) * 100;
42
+ cursorsPresence.publishPresence({
43
+ [spaceId]: { x, y, xPercent, yPercent, color: userCursorColor },
44
+ } as RoomSchema[RoomType]['presence']);
45
+ }
46
+
47
+ function onMouseMove(e: MouseEvent) {
48
+ if (!propagate) {
49
+ e.stopPropagation();
50
+ }
51
+ const rect = (e.currentTarget as Element).getBoundingClientRect();
52
+ publishCursor(rect, e);
53
+ }
54
+
55
+ function onMouseOut() {
56
+ cursorsPresence.publishPresence({
57
+ [spaceId]: undefined,
58
+ } as RoomSchema[RoomType]['presence']);
59
+ }
60
+
61
+ function onTouchMove(e: TouchEvent) {
62
+ if (e.touches.length !== 1) return;
63
+ const touch = e.touches[0];
64
+ if (touch.target instanceof Element) {
65
+ if (!propagate) {
66
+ e.stopPropagation();
67
+ }
68
+ const rect = touch.target.getBoundingClientRect();
69
+ publishCursor(rect, touch);
70
+ }
71
+ }
72
+
73
+ function onTouchEnd() {
74
+ cursorsPresence.publishPresence({
75
+ [spaceId]: undefined,
76
+ } as RoomSchema[RoomType]['presence']);
77
+ }
78
+
79
+ const defaultZ = 99999;
80
+
81
+ const peers = $derived(Object.entries(cursorsPresence.peers));
82
+ const fullPresence = $derived(
83
+ room.core._reactor.getPresence(room.type, room.id),
84
+ );
85
+ </script>
86
+
87
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
88
+ <svelte:element
89
+ this={as}
90
+ class={className}
91
+ style="position: relative; {style ?? ''}"
92
+ onmousemove={onMouseMove}
93
+ onmouseout={onMouseOut}
94
+ ontouchmove={onTouchMove}
95
+ ontouchend={onTouchEnd}
96
+ >
97
+ {#if children}
98
+ {@render children()}
99
+ {/if}
100
+ <div
101
+ style="position: absolute; top: 0; left: 0; bottom: 0; right: 0; overflow: hidden; pointer-events: none; user-select: none; z-index: {zIndex ?? defaultZ};"
102
+ >
103
+ {#each peers as [peerId, presence] (peerId)}
104
+ {@const cursor = presence[spaceId]}
105
+ {#if cursor}
106
+ <div
107
+ style="position: absolute; top: 0; left: 0; bottom: 0; right: 0; transform: translate({cursor.xPercent}%, {cursor.yPercent}%); transform-origin: 0 0; transition: transform 100ms;"
108
+ >
109
+ {#if renderCursor}
110
+ {@render renderCursor({
111
+ color: cursor.color,
112
+ presence: fullPresence?.peers[peerId],
113
+ })}
114
+ {:else}
115
+ {@const fill = cursor.color || 'black'}
116
+ <svg
117
+ style="height: 35px; width: 35px;"
118
+ viewBox="0 0 35 35"
119
+ fill="none"
120
+ xmlns="http://www.w3.org/2000/svg"
121
+ >
122
+ <g
123
+ fill="rgba(0,0,0,.2)"
124
+ transform="matrix(1, 0, 0, 1, -11.999999046325684, -8.406899452209473)"
125
+ >
126
+ <path d="m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" />
127
+ <path d="m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" />
128
+ </g>
129
+ <g
130
+ fill="white"
131
+ transform="matrix(1, 0, 0, 1, -11.999999046325684, -8.406899452209473)"
132
+ >
133
+ <path d="m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" />
134
+ <path d="m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" />
135
+ </g>
136
+ <g
137
+ fill={fill}
138
+ transform="matrix(1, 0, 0, 1, -11.999999046325684, -8.406899452209473)"
139
+ >
140
+ <path d="m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z" />
141
+ <path d="m13 10.814v11.188l2.969-2.866.428-.139h4.768z" />
142
+ </g>
143
+ </svg>
144
+ {/if}
145
+ </div>
146
+ {/if}
147
+ {/each}
148
+ </div>
149
+ </svelte:element>
@@ -0,0 +1,42 @@
1
+ import type { RoomSchemaShape } from '@instantdb/core';
2
+ import type { InstantSvelteRoom } from './InstantSvelteRoom.svelte.js';
3
+ import type { Snippet } from 'svelte';
4
+ declare function $$render<RoomSchema extends RoomSchemaShape, RoomType extends string & keyof RoomSchema>(): {
5
+ props: {
6
+ room: InstantSvelteRoom<any, RoomSchema, RoomType>;
7
+ spaceId?: string;
8
+ as?: string;
9
+ className?: string;
10
+ style?: string;
11
+ userCursorColor?: string;
12
+ children?: Snippet;
13
+ renderCursor?: Snippet<[{
14
+ color: string;
15
+ presence: RoomSchema[RoomType]["presence"];
16
+ }]>;
17
+ propagate?: boolean;
18
+ zIndex?: number;
19
+ };
20
+ exports: {};
21
+ bindings: "";
22
+ slots: {};
23
+ events: {};
24
+ };
25
+ declare class __sveltets_Render<RoomSchema extends RoomSchemaShape, RoomType extends string & keyof RoomSchema> {
26
+ props(): ReturnType<typeof $$render<RoomSchema, RoomType>>['props'];
27
+ events(): ReturnType<typeof $$render<RoomSchema, RoomType>>['events'];
28
+ slots(): ReturnType<typeof $$render<RoomSchema, RoomType>>['slots'];
29
+ bindings(): "";
30
+ exports(): {};
31
+ }
32
+ interface $$IsomorphicComponent {
33
+ new <RoomSchema extends RoomSchemaShape, RoomType extends string & keyof RoomSchema>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<RoomSchema, RoomType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<RoomSchema, RoomType>['props']>, ReturnType<__sveltets_Render<RoomSchema, RoomType>['events']>, ReturnType<__sveltets_Render<RoomSchema, RoomType>['slots']>> & {
34
+ $$bindings?: ReturnType<__sveltets_Render<RoomSchema, RoomType>['bindings']>;
35
+ } & ReturnType<__sveltets_Render<RoomSchema, RoomType>['exports']>;
36
+ <RoomSchema extends RoomSchemaShape, RoomType extends string & keyof RoomSchema>(internal: unknown, props: ReturnType<__sveltets_Render<RoomSchema, RoomType>['props']> & {}): ReturnType<__sveltets_Render<RoomSchema, RoomType>['exports']>;
37
+ z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
38
+ }
39
+ declare const Cursors: $$IsomorphicComponent;
40
+ type Cursors<RoomSchema extends RoomSchemaShape, RoomType extends string & keyof RoomSchema> = InstanceType<typeof Cursors<RoomSchema, RoomType>>;
41
+ export default Cursors;
42
+ //# sourceMappingURL=Cursors.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Cursors.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Cursors.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,iBAAS,QAAQ,CAAC,UAAU,SAAS,eAAe,EAAE,QAAQ,SAAS,MAAM,GAAG,MAAM,UAAU;;cAMtF,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC;kBACxC,MAAM;aACX,MAAM;oBACC,MAAM;gBACV,MAAM;0BACI,MAAM;mBACb,OAAO;uBACH,OAAO,CAAC,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAA;SAAE,CAAC,CAAC;oBAC3E,OAAO;iBACV,MAAM;;;;;;EA+GsG;AACzH,cAAM,iBAAiB,CAAC,UAAU,SAAS,eAAe,EAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,UAAU;IACjG,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAClE,MAAM,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACpE,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IAClE,QAAQ;IACR,OAAO;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,UAAU,SAAS,eAAe,EAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,UAAU,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACpjB,CAAC,UAAU,SAAS,eAAe,EAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3O,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,EAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACrE;AACD,QAAA,MAAM,OAAO,EAAE,qBAAmC,CAAC;AACjC,KAAK,OAAO,CAAC,UAAU,SAAS,eAAe,EAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,UAAU,IAAI,YAAY,CAAC,OAAO,OAAO,CAAC,UAAU,EAAC,QAAQ,CAAC,CAAC,CAAC;AAClJ,eAAe,OAAO,CAAC"}
@@ -0,0 +1,153 @@
1
+ import { type AuthState, type User, type ConnectionStatus, type TransactionChunk, type RoomSchemaShape, type InstaQLOptions, type InstantConfig, type PageInfoResponse, type InstaQLLifecycleState, type InstaQLResponse, type ValidQuery, Auth, Storage, InstantCoreDatabase, InstantSchemaDef, RoomsOf, IInstantDatabase } from '@instantdb/core';
2
+ import { InstantSvelteRoom } from './InstantSvelteRoom.svelte.js';
3
+ export declare class InstantSvelteDatabase<Schema extends InstantSchemaDef<any, any, any>, UseDates extends boolean = false, Rooms extends RoomSchemaShape = RoomsOf<Schema>> implements IInstantDatabase<Schema> {
4
+ tx: import("@instantdb/core").TxChunk<Schema>;
5
+ auth: Auth;
6
+ storage: Storage;
7
+ core: InstantCoreDatabase<Schema, UseDates>;
8
+ constructor(core: InstantCoreDatabase<Schema, UseDates>);
9
+ /**
10
+ * Returns a unique ID for a given `name`. It's stored in local storage,
11
+ * so you will get the same ID across sessions.
12
+ *
13
+ * @example
14
+ * const deviceId = await db.getLocalId('device');
15
+ */
16
+ getLocalId: (name: string) => Promise<string>;
17
+ /**
18
+ * Use this to write data! You can create, update, delete, and link objects
19
+ *
20
+ * @see https://instantdb.com/docs/instaml
21
+ *
22
+ * @example
23
+ * const goalId = id();
24
+ * db.transact(db.tx.goals[goalId].update({title: "Get fit"}))
25
+ */
26
+ transact: (chunks: TransactionChunk<any, any> | TransactionChunk<any, any>[]) => Promise<import("@instantdb/core").TransactionResult>;
27
+ /**
28
+ * One time query for the logged in state.
29
+ *
30
+ * @see https://instantdb.com/docs/auth
31
+ * @example
32
+ * const user = await db.getAuth();
33
+ * console.log('logged in as', user.email)
34
+ */
35
+ getAuth(): Promise<User | null>;
36
+ /**
37
+ * Use this for one-off queries.
38
+ * Returns local data if available, otherwise fetches from the server.
39
+ *
40
+ * @see https://instantdb.com/docs/instaql
41
+ *
42
+ * @example
43
+ * const resp = await db.queryOnce({ goals: {} });
44
+ * console.log(resp.data.goals)
45
+ */
46
+ queryOnce: <Q extends ValidQuery<Q, Schema>>(query: Q, opts?: InstaQLOptions) => Promise<{
47
+ data: InstaQLResponse<Schema, Q, UseDates>;
48
+ pageInfo: PageInfoResponse<Q>;
49
+ }>;
50
+ /**
51
+ * Use this to query your data!
52
+ *
53
+ * @see https://instantdb.com/docs/instaql
54
+ *
55
+ * @example
56
+ * const state = db.useQuery({ goals: {} });
57
+ * // state.isLoading, state.error, state.data
58
+ */
59
+ useQuery: <Q extends ValidQuery<Q, Schema>>(query: (() => null | Q) | null | Q, opts?: InstaQLOptions) => InstaQLLifecycleState<Schema, Q, UseDates>;
60
+ /**
61
+ * Listen for the logged in state. This is useful
62
+ * for deciding when to show a login screen.
63
+ *
64
+ * @see https://instantdb.com/docs/auth
65
+ * @example
66
+ * const auth = db.useAuth();
67
+ * // auth.isLoading, auth.user, auth.error
68
+ */
69
+ useAuth: () => AuthState;
70
+ /**
71
+ * Subscribe to the currently logged in user.
72
+ * If the user is not logged in, this will throw an Error.
73
+ *
74
+ * @see https://instantdb.com/docs/auth
75
+ * @example
76
+ * const user = db.useUser();
77
+ * // user.email, user.id, etc.
78
+ * // Throws if not logged in
79
+ */
80
+ useUser: () => User;
81
+ /**
82
+ * Listen for connection status changes to Instant.
83
+ *
84
+ * @see https://www.instantdb.com/docs/patterns#connection-status
85
+ * @example
86
+ * const status = db.useConnectionStatus();
87
+ * // status.current
88
+ */
89
+ useConnectionStatus: () => {
90
+ current: ConnectionStatus;
91
+ };
92
+ /**
93
+ * A hook that returns a unique ID for a given `name`. localIds are
94
+ * stored in local storage, so you will get the same ID across sessions.
95
+ *
96
+ * Initially returns `null`, and then loads the localId.
97
+ *
98
+ * @example
99
+ * const deviceId = db.useLocalId('device');
100
+ * // deviceId.current is null initially, then the ID string
101
+ */
102
+ useLocalId: (name: string) => {
103
+ current: string | null;
104
+ };
105
+ /**
106
+ * Obtain a handle to a room, which allows you to listen to topics and presence data
107
+ *
108
+ * @see https://instantdb.com/docs/presence-and-topics
109
+ *
110
+ * @example
111
+ * const room = db.room('chat', roomId);
112
+ * const presence = db.rooms.usePresence(room);
113
+ */
114
+ room<RoomType extends keyof Rooms>(type?: RoomType, id?: string): InstantSvelteRoom<Schema, Rooms, RoomType>;
115
+ /**
116
+ * Hooks for working with rooms
117
+ *
118
+ * @see https://instantdb.com/docs/presence-and-topics
119
+ *
120
+ * @example
121
+ * const room = db.room('chat', roomId);
122
+ * const presence = db.rooms.usePresence(room);
123
+ * const publish = db.rooms.usePublishTopic(room, 'emoji');
124
+ */
125
+ rooms: {
126
+ useTopicEffect: typeof import("./InstantSvelteRoom.svelte.js").useTopicEffect;
127
+ usePublishTopic: typeof import("./InstantSvelteRoom.svelte.js").usePublishTopic;
128
+ usePresence: typeof import("./InstantSvelteRoom.svelte.js").usePresence;
129
+ useSyncPresence: typeof import("./InstantSvelteRoom.svelte.js").useSyncPresence;
130
+ useTypingIndicator: typeof import("./InstantSvelteRoom.svelte.js").useTypingIndicator;
131
+ };
132
+ }
133
+ /**
134
+ * The first step: init your application!
135
+ *
136
+ * Visit https://instantdb.com/dash to get your `appId` :)
137
+ *
138
+ * @example
139
+ * import { init } from "@instantdb/svelte"
140
+ *
141
+ * const db = init({ appId: "my-app-id" })
142
+ *
143
+ * // You can also provide a schema for type safety and editor autocomplete!
144
+ *
145
+ * import { init } from "@instantdb/svelte"
146
+ * import schema from "../instant.schema.ts";
147
+ *
148
+ * const db = init({ appId: "my-app-id", schema })
149
+ */
150
+ export declare function init<Schema extends InstantSchemaDef<any, any, any>, UseDates extends boolean = false>(config: Omit<InstantConfig<Schema, UseDates>, 'useDateObjects'> & {
151
+ useDateObjects?: UseDates;
152
+ }): InstantSvelteDatabase<Schema, UseDates>;
153
+ //# sourceMappingURL=InstantSvelteDatabase.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InstantSvelteDatabase.svelte.d.ts","sourceRoot":"","sources":["../src/lib/InstantSvelteDatabase.svelte.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,265 @@
1
+ import { txInit, init as core_init, coerceQuery, InstantError, } from '@instantdb/core';
2
+ import { InstantSvelteRoom, rooms } from './InstantSvelteRoom.svelte.js';
3
+ import version from './version.js';
4
+ const defaultState = {
5
+ isLoading: true,
6
+ data: undefined,
7
+ pageInfo: undefined,
8
+ error: undefined,
9
+ };
10
+ const defaultAuthState = {
11
+ isLoading: true,
12
+ user: undefined,
13
+ error: undefined,
14
+ };
15
+ function stateForResult(result) {
16
+ return {
17
+ isLoading: !Boolean(result),
18
+ data: undefined,
19
+ pageInfo: undefined,
20
+ error: undefined,
21
+ ...(result ? result : {}),
22
+ };
23
+ }
24
+ export class InstantSvelteDatabase {
25
+ tx = txInit();
26
+ auth;
27
+ storage;
28
+ core;
29
+ constructor(core) {
30
+ this.core = core;
31
+ this.auth = this.core.auth;
32
+ this.storage = this.core.storage;
33
+ }
34
+ /**
35
+ * Returns a unique ID for a given `name`. It's stored in local storage,
36
+ * so you will get the same ID across sessions.
37
+ *
38
+ * @example
39
+ * const deviceId = await db.getLocalId('device');
40
+ */
41
+ getLocalId = (name) => {
42
+ return this.core.getLocalId(name);
43
+ };
44
+ /**
45
+ * Use this to write data! You can create, update, delete, and link objects
46
+ *
47
+ * @see https://instantdb.com/docs/instaml
48
+ *
49
+ * @example
50
+ * const goalId = id();
51
+ * db.transact(db.tx.goals[goalId].update({title: "Get fit"}))
52
+ */
53
+ transact = (chunks) => {
54
+ return this.core.transact(chunks);
55
+ };
56
+ /**
57
+ * One time query for the logged in state.
58
+ *
59
+ * @see https://instantdb.com/docs/auth
60
+ * @example
61
+ * const user = await db.getAuth();
62
+ * console.log('logged in as', user.email)
63
+ */
64
+ getAuth() {
65
+ return this.core.getAuth();
66
+ }
67
+ /**
68
+ * Use this for one-off queries.
69
+ * Returns local data if available, otherwise fetches from the server.
70
+ *
71
+ * @see https://instantdb.com/docs/instaql
72
+ *
73
+ * @example
74
+ * const resp = await db.queryOnce({ goals: {} });
75
+ * console.log(resp.data.goals)
76
+ */
77
+ queryOnce = (query, opts) => {
78
+ return this.core.queryOnce(query, opts);
79
+ };
80
+ // -----------
81
+ // Svelte reactive hooks
82
+ /**
83
+ * Use this to query your data!
84
+ *
85
+ * @see https://instantdb.com/docs/instaql
86
+ *
87
+ * @example
88
+ * const state = db.useQuery({ goals: {} });
89
+ * // state.isLoading, state.error, state.data
90
+ */
91
+ useQuery = (query, opts) => {
92
+ let result = $state({
93
+ ...defaultState,
94
+ });
95
+ $effect(() => {
96
+ const resolvedQuery = typeof query === 'function' ? query() : query;
97
+ if (!resolvedQuery) {
98
+ result.isLoading = true;
99
+ result.data = undefined;
100
+ result.pageInfo = undefined;
101
+ result.error = undefined;
102
+ return;
103
+ }
104
+ let q = resolvedQuery;
105
+ if (opts && 'ruleParams' in opts) {
106
+ q = { $$ruleParams: opts['ruleParams'], ...q };
107
+ }
108
+ const coerced = coerceQuery(q);
109
+ const prev = this.core._reactor.getPreviousResult(coerced);
110
+ if (prev) {
111
+ const prevState = stateForResult(prev);
112
+ result.isLoading = prevState.isLoading;
113
+ result.data = prevState.data;
114
+ result.pageInfo = prevState.pageInfo;
115
+ result.error = prevState.error;
116
+ }
117
+ const unsub = this.core.subscribeQuery(coerced, (r) => {
118
+ result.isLoading = false;
119
+ result.data = r.data;
120
+ result.pageInfo = r.pageInfo;
121
+ result.error = r.error;
122
+ });
123
+ return unsub;
124
+ });
125
+ return result;
126
+ };
127
+ /**
128
+ * Listen for the logged in state. This is useful
129
+ * for deciding when to show a login screen.
130
+ *
131
+ * @see https://instantdb.com/docs/auth
132
+ * @example
133
+ * const auth = db.useAuth();
134
+ * // auth.isLoading, auth.user, auth.error
135
+ */
136
+ useAuth = () => {
137
+ let result = $state(this.core._reactor._currentUserCached
138
+ ? { ...this.core._reactor._currentUserCached }
139
+ : { ...defaultAuthState });
140
+ $effect(() => {
141
+ const unsub = this.core.subscribeAuth((auth) => {
142
+ result.isLoading = false;
143
+ result.user = auth.user;
144
+ result.error = auth.error;
145
+ });
146
+ return unsub;
147
+ });
148
+ return result;
149
+ };
150
+ /**
151
+ * Subscribe to the currently logged in user.
152
+ * If the user is not logged in, this will throw an Error.
153
+ *
154
+ * @see https://instantdb.com/docs/auth
155
+ * @example
156
+ * const user = db.useUser();
157
+ * // user.email, user.id, etc.
158
+ * // Throws if not logged in
159
+ */
160
+ useUser = () => {
161
+ const auth = this.useAuth();
162
+ // Return a proxy that always reads from the latest auth state
163
+ return new Proxy({}, {
164
+ get(_target, prop, receiver) {
165
+ if (!auth.user) {
166
+ throw new InstantError('useUser must be used within an auth-protected route');
167
+ }
168
+ return Reflect.get(auth.user, prop, receiver);
169
+ },
170
+ });
171
+ };
172
+ /**
173
+ * Listen for connection status changes to Instant.
174
+ *
175
+ * @see https://www.instantdb.com/docs/patterns#connection-status
176
+ * @example
177
+ * const status = db.useConnectionStatus();
178
+ * // status.current
179
+ */
180
+ useConnectionStatus = () => {
181
+ let result = $state({
182
+ current: this.core._reactor.status,
183
+ });
184
+ $effect(() => {
185
+ const unsub = this.core.subscribeConnectionStatus((newStatus) => {
186
+ result.current = newStatus;
187
+ });
188
+ return unsub;
189
+ });
190
+ return result;
191
+ };
192
+ /**
193
+ * A hook that returns a unique ID for a given `name`. localIds are
194
+ * stored in local storage, so you will get the same ID across sessions.
195
+ *
196
+ * Initially returns `null`, and then loads the localId.
197
+ *
198
+ * @example
199
+ * const deviceId = db.useLocalId('device');
200
+ * // deviceId.current is null initially, then the ID string
201
+ */
202
+ useLocalId = (name) => {
203
+ let result = $state({ current: null });
204
+ $effect(() => {
205
+ let mounted = true;
206
+ this.getLocalId(name).then((id) => {
207
+ if (mounted) {
208
+ result.current = id;
209
+ }
210
+ });
211
+ return () => {
212
+ mounted = false;
213
+ };
214
+ });
215
+ return result;
216
+ };
217
+ /**
218
+ * Obtain a handle to a room, which allows you to listen to topics and presence data
219
+ *
220
+ * @see https://instantdb.com/docs/presence-and-topics
221
+ *
222
+ * @example
223
+ * const room = db.room('chat', roomId);
224
+ * const presence = db.rooms.usePresence(room);
225
+ */
226
+ room(type = '_defaultRoomType', id = '_defaultRoomId') {
227
+ return new InstantSvelteRoom(this.core, type, id);
228
+ }
229
+ /**
230
+ * Hooks for working with rooms
231
+ *
232
+ * @see https://instantdb.com/docs/presence-and-topics
233
+ *
234
+ * @example
235
+ * const room = db.room('chat', roomId);
236
+ * const presence = db.rooms.usePresence(room);
237
+ * const publish = db.rooms.usePublishTopic(room, 'emoji');
238
+ */
239
+ rooms = rooms;
240
+ }
241
+ // -----------
242
+ // init
243
+ /**
244
+ * The first step: init your application!
245
+ *
246
+ * Visit https://instantdb.com/dash to get your `appId` :)
247
+ *
248
+ * @example
249
+ * import { init } from "@instantdb/svelte"
250
+ *
251
+ * const db = init({ appId: "my-app-id" })
252
+ *
253
+ * // You can also provide a schema for type safety and editor autocomplete!
254
+ *
255
+ * import { init } from "@instantdb/svelte"
256
+ * import schema from "../instant.schema.ts";
257
+ *
258
+ * const db = init({ appId: "my-app-id", schema })
259
+ */
260
+ export function init(config) {
261
+ const coreDb = core_init(config, undefined, undefined, {
262
+ '@instantdb/svelte': version,
263
+ });
264
+ return new InstantSvelteDatabase(coreDb);
265
+ }
@@ -0,0 +1,82 @@
1
+ import { type PresenceOpts, type PresenceResponse, type RoomSchemaShape, InstantCoreDatabase, InstantSchemaDef } from '@instantdb/core';
2
+ export type PresenceHandle<PresenceShape, Keys extends keyof PresenceShape> = PresenceResponse<PresenceShape, Keys> & {
3
+ publishPresence: (data: Partial<PresenceShape>) => void;
4
+ };
5
+ export type TypingIndicatorOpts = {
6
+ timeout?: number | null;
7
+ stopOnEnter?: boolean;
8
+ writeOnly?: boolean;
9
+ };
10
+ export type TypingIndicatorHandle<PresenceShape> = {
11
+ active: PresenceShape[];
12
+ setActive(active: boolean): void;
13
+ inputProps: {
14
+ onKeyDown: (e: KeyboardEvent) => void;
15
+ onBlur: () => void;
16
+ };
17
+ };
18
+ export declare const defaultActivityStopTimeout = 1000;
19
+ /**
20
+ * Listen for broadcasted events given a room and topic.
21
+ *
22
+ * @see https://instantdb.com/docs/presence-and-topics
23
+ * @example
24
+ * const room = db.room('chats', roomId);
25
+ * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => {
26
+ * console.log(peer.name, 'sent', message);
27
+ * });
28
+ */
29
+ export declare function useTopicEffect<RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema, TopicType extends keyof RoomSchema[RoomType]['topics']>(room: InstantSvelteRoom<any, RoomSchema, RoomType>, topic: TopicType, onEvent: (event: RoomSchema[RoomType]['topics'][TopicType], peer: RoomSchema[RoomType]['presence']) => any): void;
30
+ /**
31
+ * Broadcast an event to a room.
32
+ *
33
+ * @see https://instantdb.com/docs/presence-and-topics
34
+ * @example
35
+ * const room = db.room('chat', roomId);
36
+ * const publishTopic = db.rooms.usePublishTopic(room, 'emoji');
37
+ * publishTopic({ emoji: "🔥" });
38
+ */
39
+ export declare function usePublishTopic<RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema, TopicType extends keyof RoomSchema[RoomType]['topics']>(room: InstantSvelteRoom<any, RoomSchema, RoomType>, topic: TopicType): (data: RoomSchema[RoomType]['topics'][TopicType]) => void;
40
+ /**
41
+ * Listen for peer's presence data in a room, and publish the current user's presence.
42
+ *
43
+ * @see https://instantdb.com/docs/presence-and-topics
44
+ * @example
45
+ * const room = db.room('chat', roomId);
46
+ * const presence = db.rooms.usePresence(room, { keys: ["name", "avatar"] });
47
+ * // presence.peers, presence.isLoading, presence.publishPresence
48
+ */
49
+ export declare function usePresence<RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema, Keys extends keyof RoomSchema[RoomType]['presence']>(room: InstantSvelteRoom<any, RoomSchema, RoomType>, opts?: PresenceOpts<RoomSchema[RoomType]['presence'], Keys>): PresenceHandle<RoomSchema[RoomType]['presence'], Keys>;
50
+ /**
51
+ * Publishes presence data to a room
52
+ *
53
+ * @see https://instantdb.com/docs/presence-and-topics
54
+ * @example
55
+ * const room = db.room('chat', roomId);
56
+ * db.rooms.useSyncPresence(room, { nickname });
57
+ */
58
+ export declare function useSyncPresence<RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema>(room: InstantSvelteRoom<any, RoomSchema, RoomType>, data: Partial<RoomSchema[RoomType]['presence']>, deps?: any[]): void;
59
+ /**
60
+ * Manage typing indicator state
61
+ *
62
+ * @see https://instantdb.com/docs/presence-and-topics
63
+ * @example
64
+ * const room = db.room('chat', roomId);
65
+ * const typing = db.rooms.useTypingIndicator(room, 'chat-input');
66
+ * // typing.active, typing.setActive(bool), typing.inputProps
67
+ */
68
+ export declare function useTypingIndicator<RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema>(room: InstantSvelteRoom<any, RoomSchema, RoomType>, inputName: string, opts?: TypingIndicatorOpts): TypingIndicatorHandle<RoomSchema[RoomType]['presence']>;
69
+ export declare const rooms: {
70
+ useTopicEffect: typeof useTopicEffect;
71
+ usePublishTopic: typeof usePublishTopic;
72
+ usePresence: typeof usePresence;
73
+ useSyncPresence: typeof useSyncPresence;
74
+ useTypingIndicator: typeof useTypingIndicator;
75
+ };
76
+ export declare class InstantSvelteRoom<Schema extends InstantSchemaDef<any, any, any>, RoomSchema extends RoomSchemaShape, RoomType extends keyof RoomSchema> {
77
+ core: InstantCoreDatabase<Schema, boolean>;
78
+ type: RoomType;
79
+ id: string;
80
+ constructor(core: InstantCoreDatabase<Schema, boolean>, type: RoomType, id: string);
81
+ }
82
+ //# sourceMappingURL=InstantSvelteRoom.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InstantSvelteRoom.svelte.d.ts","sourceRoot":"","sources":["../src/lib/InstantSvelteRoom.svelte.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,193 @@
1
+ export const defaultActivityStopTimeout = 1_000;
2
+ // ------
3
+ // Topics
4
+ /**
5
+ * Listen for broadcasted events given a room and topic.
6
+ *
7
+ * @see https://instantdb.com/docs/presence-and-topics
8
+ * @example
9
+ * const room = db.room('chats', roomId);
10
+ * db.rooms.useTopicEffect(room, 'emoji', (message, peer) => {
11
+ * console.log(peer.name, 'sent', message);
12
+ * });
13
+ */
14
+ export function useTopicEffect(room, topic, onEvent) {
15
+ $effect(() => {
16
+ const unsub = room.core._reactor.subscribeTopic(room.type, room.id, topic, (event, peer) => {
17
+ onEvent(event, peer);
18
+ });
19
+ return unsub;
20
+ });
21
+ }
22
+ /**
23
+ * Broadcast an event to a room.
24
+ *
25
+ * @see https://instantdb.com/docs/presence-and-topics
26
+ * @example
27
+ * const room = db.room('chat', roomId);
28
+ * const publishTopic = db.rooms.usePublishTopic(room, 'emoji');
29
+ * publishTopic({ emoji: "🔥" });
30
+ */
31
+ export function usePublishTopic(room, topic) {
32
+ $effect(() => {
33
+ const unsub = room.core._reactor.joinRoom(room.type, room.id);
34
+ return unsub;
35
+ });
36
+ return (data) => {
37
+ room.core._reactor.publishTopic({
38
+ roomType: room.type,
39
+ roomId: room.id,
40
+ topic,
41
+ data,
42
+ });
43
+ };
44
+ }
45
+ // ---------
46
+ // Presence
47
+ /**
48
+ * Listen for peer's presence data in a room, and publish the current user's presence.
49
+ *
50
+ * @see https://instantdb.com/docs/presence-and-topics
51
+ * @example
52
+ * const room = db.room('chat', roomId);
53
+ * const presence = db.rooms.usePresence(room, { keys: ["name", "avatar"] });
54
+ * // presence.peers, presence.isLoading, presence.publishPresence
55
+ */
56
+ export function usePresence(room, opts = {}) {
57
+ const initial = (room.core._reactor.getPresence(room.type, room.id, opts) ?? {
58
+ peers: {},
59
+ isLoading: true,
60
+ });
61
+ let result = $state({
62
+ ...initial,
63
+ publishPresence: (data) => {
64
+ room.core._reactor.publishPresence(room.type, room.id, data);
65
+ },
66
+ });
67
+ $effect(() => {
68
+ const unsub = room.core._reactor.subscribePresence(room.type, room.id, opts, (data) => {
69
+ result.peers = data.peers;
70
+ result.isLoading = data.isLoading;
71
+ if ('user' in data) {
72
+ result.user = data.user;
73
+ }
74
+ });
75
+ return unsub;
76
+ });
77
+ return result;
78
+ }
79
+ /**
80
+ * Publishes presence data to a room
81
+ *
82
+ * @see https://instantdb.com/docs/presence-and-topics
83
+ * @example
84
+ * const room = db.room('chat', roomId);
85
+ * db.rooms.useSyncPresence(room, { nickname });
86
+ */
87
+ export function useSyncPresence(room, data, deps) {
88
+ $effect(() => {
89
+ const unsub = room.core._reactor.joinRoom(room.type, room.id, data);
90
+ return unsub;
91
+ });
92
+ $effect(() => {
93
+ if (deps) {
94
+ // Track deps by reading them
95
+ deps.forEach((d) => (typeof d === 'function' ? d() : d));
96
+ }
97
+ else {
98
+ JSON.stringify(data);
99
+ }
100
+ room.core._reactor.publishPresence(room.type, room.id, data);
101
+ });
102
+ }
103
+ // -----------------
104
+ // Typing Indicator
105
+ /**
106
+ * Manage typing indicator state
107
+ *
108
+ * @see https://instantdb.com/docs/presence-and-topics
109
+ * @example
110
+ * const room = db.room('chat', roomId);
111
+ * const typing = db.rooms.useTypingIndicator(room, 'chat-input');
112
+ * // typing.active, typing.setActive(bool), typing.inputProps
113
+ */
114
+ export function useTypingIndicator(room, inputName, opts = {}) {
115
+ let timeoutId = null;
116
+ const presence = rooms.usePresence(room, {
117
+ keys: [inputName],
118
+ });
119
+ let _active = $state([]);
120
+ $effect(() => {
121
+ if (opts?.writeOnly) {
122
+ _active = [];
123
+ return;
124
+ }
125
+ // Read presence to track it
126
+ const _peers = presence.peers;
127
+ const presenceSnapshot = room.core._reactor.getPresence(room.type, room.id);
128
+ _active = Object.values(presenceSnapshot?.peers ?? {}).filter((p) => p[inputName] === true);
129
+ });
130
+ const setActive = (isActive) => {
131
+ room.core._reactor.publishPresence(room.type, room.id, {
132
+ [inputName]: isActive ? true : null,
133
+ });
134
+ if (timeoutId) {
135
+ clearTimeout(timeoutId);
136
+ timeoutId = null;
137
+ }
138
+ if (!isActive)
139
+ return;
140
+ if (opts?.timeout === null || opts?.timeout === 0)
141
+ return;
142
+ timeoutId = setTimeout(() => {
143
+ room.core._reactor.publishPresence(room.type, room.id, {
144
+ [inputName]: null,
145
+ });
146
+ }, opts?.timeout ?? defaultActivityStopTimeout);
147
+ };
148
+ $effect(() => {
149
+ return () => {
150
+ if (timeoutId) {
151
+ clearTimeout(timeoutId);
152
+ timeoutId = null;
153
+ }
154
+ setActive(false);
155
+ };
156
+ });
157
+ const onKeyDown = (e) => {
158
+ const isEnter = opts?.stopOnEnter && e.key === 'Enter';
159
+ const isActive = !isEnter;
160
+ setActive(isActive);
161
+ };
162
+ const onBlur = () => {
163
+ setActive(false);
164
+ };
165
+ return {
166
+ get active() {
167
+ return _active;
168
+ },
169
+ setActive,
170
+ inputProps: { onKeyDown, onBlur },
171
+ };
172
+ }
173
+ // --------------
174
+ // Hooks namespace
175
+ export const rooms = {
176
+ useTopicEffect,
177
+ usePublishTopic,
178
+ usePresence,
179
+ useSyncPresence,
180
+ useTypingIndicator,
181
+ };
182
+ // ------------
183
+ // Class
184
+ export class InstantSvelteRoom {
185
+ core;
186
+ type;
187
+ id;
188
+ constructor(core, type, id) {
189
+ this.core = core;
190
+ this.type = type;
191
+ this.id = id;
192
+ }
193
+ }
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type { InstantSchemaDef } from '@instantdb/core';
3
+ import type { InstantSvelteDatabase } from './InstantSvelteDatabase.svelte.js';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ let { db, children }: {
7
+ db: InstantSvelteDatabase<InstantSchemaDef<any, any, any>>;
8
+ children: Snippet;
9
+ } = $props();
10
+
11
+ const auth = db.useAuth();
12
+ </script>
13
+
14
+ {#if !auth.isLoading && !auth.error && auth.user}
15
+ {@render children()}
16
+ {/if}
@@ -0,0 +1,11 @@
1
+ import type { InstantSchemaDef } from '@instantdb/core';
2
+ import type { InstantSvelteDatabase } from './InstantSvelteDatabase.svelte.js';
3
+ import type { Snippet } from 'svelte';
4
+ type $$ComponentProps = {
5
+ db: InstantSvelteDatabase<InstantSchemaDef<any, any, any>>;
6
+ children: Snippet;
7
+ };
8
+ declare const SignedIn: import("svelte").Component<$$ComponentProps, {}, "">;
9
+ type SignedIn = ReturnType<typeof SignedIn>;
10
+ export default SignedIn;
11
+ //# sourceMappingURL=SignedIn.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignedIn.svelte.d.ts","sourceRoot":"","sources":["../src/lib/SignedIn.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAErC,KAAK,gBAAgB,GAAI;IACtB,EAAE,EAAE,qBAAqB,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAiBJ,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type { InstantSchemaDef } from '@instantdb/core';
3
+ import type { InstantSvelteDatabase } from './InstantSvelteDatabase.svelte.js';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ let { db, children }: {
7
+ db: InstantSvelteDatabase<InstantSchemaDef<any, any, any>>;
8
+ children: Snippet;
9
+ } = $props();
10
+
11
+ const auth = db.useAuth();
12
+ </script>
13
+
14
+ {#if !auth.isLoading && !auth.user}
15
+ {@render children()}
16
+ {/if}
@@ -0,0 +1,11 @@
1
+ import type { InstantSchemaDef } from '@instantdb/core';
2
+ import type { InstantSvelteDatabase } from './InstantSvelteDatabase.svelte.js';
3
+ import type { Snippet } from 'svelte';
4
+ type $$ComponentProps = {
5
+ db: InstantSvelteDatabase<InstantSchemaDef<any, any, any>>;
6
+ children: Snippet;
7
+ };
8
+ declare const SignedOut: import("svelte").Component<$$ComponentProps, {}, "">;
9
+ type SignedOut = ReturnType<typeof SignedOut>;
10
+ export default SignedOut;
11
+ //# sourceMappingURL=SignedOut.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignedOut.svelte.d.ts","sourceRoot":"","sources":["../src/lib/SignedOut.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAErC,KAAK,gBAAgB,GAAI;IACtB,EAAE,EAAE,qBAAqB,CAAC,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAiBJ,QAAA,MAAM,SAAS,sDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { id, tx, lookup, i, InstantAPIError, SyncTableCallbackEventType, type QueryResponse, type InstantQuery, type InstantQueryResult, type InstantSchema, type InstantObject, type InstantEntity, type InstantSchemaDatabase, type InstantUnknownSchemaDef, type IInstantDatabase, type User, type AuthState, type Query, type Config, type InstaQLParams, type ConnectionStatus, type ValidQuery, type PresencePeer, type AttrsDefs, type CardinalityKind, type DataAttrDef, type EntitiesDef, type EntitiesWithLinks, type EntityDef, type InstantGraph, type InstantConfig, type LinkAttrDef, type LinkDef, type LinksDef, type ResolveAttrs, type ValueTypes, type InstaQLEntity, type InstaQLFields, type InstaQLResult, type InstaQLEntitySubquery, type RoomsOf, type RoomsDef, type PresenceOf, type TopicsOf, type TopicOf, type RoomHandle, type TransactionChunk, type InstantUnknownSchema, type InstantSchemaDef, type BackwardsCompatibleSchema, type InstantRules, type UpdateParams, type LinkParams, type CreateParams, type ExchangeCodeForTokenParams, type SendMagicCodeParams, type SendMagicCodeResponse, type SignInWithIdTokenParams, type VerifyMagicCodeParams, type VerifyResponse, type FileOpts, type UploadFileResponse, type DeleteFileResponse, type SyncTableCallback, type SyncTableCallbackEvent, type SyncTableInitialSyncBatch, type SyncTableInitialSyncComplete, type SyncTableSyncTransaction, type SyncTableLoadFromStorage, type SyncTableSetupError, StoreInterface, createInstantRouteHandler, type StoreInterfaceStoreName } from '@instantdb/core';
2
+ import { InstantSvelteDatabase } from './InstantSvelteDatabase.svelte.js';
3
+ import { init } from './InstantSvelteDatabase.svelte.js';
4
+ import { InstantSvelteRoom } from './InstantSvelteRoom.svelte.js';
5
+ import SignedIn from './SignedIn.svelte';
6
+ import SignedOut from './SignedOut.svelte';
7
+ import Cursors from './Cursors.svelte';
8
+ export { id, tx, lookup, init, InstantSvelteDatabase, InstantSvelteRoom, SignedIn, SignedOut, Cursors, i, InstantAPIError, SyncTableCallbackEventType, type Config, type InstantConfig, type InstantUnknownSchemaDef, type Query, type QueryResponse, type InstantObject, type User, type AuthState, type ConnectionStatus, type InstantQuery, type InstantQueryResult, type InstantSchema, type InstantEntity, type InstantSchemaDatabase, type IInstantDatabase, type InstaQLParams, type ValidQuery, type InstaQLFields, type PresencePeer, type AttrsDefs, type CardinalityKind, type DataAttrDef, type EntitiesDef, type EntitiesWithLinks, type EntityDef, type InstantGraph, type LinkAttrDef, type LinkDef, type LinksDef, type ResolveAttrs, type ValueTypes, type InstaQLEntity, type InstaQLResult, type InstaQLEntitySubquery, type RoomsOf, type RoomsDef, type TransactionChunk, type PresenceOf, type TopicsOf, type TopicOf, type RoomHandle, type InstantUnknownSchema, type InstantSchemaDef, type BackwardsCompatibleSchema, type InstantRules, type UpdateParams, type LinkParams, type CreateParams, type ExchangeCodeForTokenParams, type SendMagicCodeParams, type SendMagicCodeResponse, type SignInWithIdTokenParams, type VerifyMagicCodeParams, type VerifyResponse, type FileOpts, type UploadFileResponse, type DeleteFileResponse, StoreInterface, type StoreInterfaceStoreName, type SyncTableCallback, type SyncTableCallbackEvent, type SyncTableInitialSyncBatch, type SyncTableInitialSyncComplete, type SyncTableSyncTransaction, type SyncTableLoadFromStorage, type SyncTableSetupError, createInstantRouteHandler, };
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ import { id, tx, lookup, i,
2
+ // error
3
+ InstantAPIError,
4
+ // sync table enums
5
+ SyncTableCallbackEventType, StoreInterface, createInstantRouteHandler, } from '@instantdb/core';
6
+ import { InstantSvelteDatabase } from './InstantSvelteDatabase.svelte.js';
7
+ import { init } from './InstantSvelteDatabase.svelte.js';
8
+ import { InstantSvelteRoom } from './InstantSvelteRoom.svelte.js';
9
+ import SignedIn from './SignedIn.svelte';
10
+ import SignedOut from './SignedOut.svelte';
11
+ import Cursors from './Cursors.svelte';
12
+ export { id, tx, lookup, init, InstantSvelteDatabase, InstantSvelteRoom, SignedIn, SignedOut, Cursors, i,
13
+ // error
14
+ InstantAPIError,
15
+ // sync table enums
16
+ SyncTableCallbackEventType,
17
+ // custom store
18
+ StoreInterface,
19
+ // Server helper
20
+ createInstantRouteHandler, };
@@ -0,0 +1,3 @@
1
+ import { version } from '@instantdb/version';
2
+ export default version;
3
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/lib/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,eAAe,OAAO,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { version } from '@instantdb/version';
2
+ export default version;
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@instantdb/svelte",
3
+ "type": "module",
4
+ "version": "0.0.0",
5
+ "description": "Svelte client for InstantDB",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/instantdb/instant.git",
9
+ "directory": "client/packages/svelte"
10
+ },
11
+ "scripts": {
12
+ "test": "vitest run",
13
+ "test:watch": "vitest",
14
+ "check": "svelte-check --tsconfig ./tsconfig.json",
15
+ "build": "rm -rf dist && svelte-package -i src/lib -o dist",
16
+ "dev": "svelte-package -i src/lib -o dist --watch",
17
+ "publish-package": "pnpm pack && npm publish *.tgz --access public"
18
+ },
19
+ "svelte": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ "./package.json": "./package.json",
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "svelte": "./dist/index.js",
26
+ "default": "./dist/index.js"
27
+ }
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "!dist/**/*.test.*",
32
+ "!dist/**/*.spec.*"
33
+ ],
34
+ "peerDependencies": {
35
+ "svelte": "^5.0.0"
36
+ },
37
+ "dependencies": {
38
+ "@instantdb/core": "workspace:*",
39
+ "@instantdb/version": "workspace:*"
40
+ },
41
+ "devDependencies": {
42
+ "@sveltejs/package": "^2.3.0",
43
+ "@sveltejs/vite-plugin-svelte": "^4.0.0",
44
+ "@testing-library/svelte": "^5.2.0",
45
+ "jsdom": "^25.0.0",
46
+ "svelte": "^5.0.0",
47
+ "svelte-check": "^4.0.0",
48
+ "typescript": "^5.0.0",
49
+ "vite": "^5.2.0",
50
+ "vitest": "^2.0.0"
51
+ }
52
+ }