@pikku/kysely 0.12.9 → 0.12.10
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/CHANGELOG.md +14 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/kysely-channel-store.d.ts +3 -4
- package/dist/src/kysely-channel-store.js +6 -6
- package/dist/src/kysely-session-store.d.ts +13 -0
- package/dist/src/kysely-session-store.js +54 -0
- package/dist/src/kysely-tables.d.ts +8 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/kysely-channel-store.ts +8 -9
- package/src/kysely-services.test.ts +6 -0
- package/src/kysely-session-store.ts +73 -0
- package/src/kysely-tables.ts +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
## 0.12.0
|
|
2
2
|
|
|
3
|
+
## 0.12.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 311c0c4: Unify session persistence through SessionStore, remove session blob from ChannelStore
|
|
8
|
+
|
|
9
|
+
- PikkuSessionService now persists sessions via SessionStore on set()/clear() instead of every function call
|
|
10
|
+
- ChannelStore no longer stores session data — maps channelId to pikkuUserId only
|
|
11
|
+
- ChannelStore API: setUserSession/getChannelAndSession replaced with setPikkuUserId/getChannel
|
|
12
|
+
- Serverless channel runner resolves sessions from SessionStore using pikkuUserId from ChannelStore
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [311c0c4]
|
|
15
|
+
- @pikku/core@0.12.18
|
|
16
|
+
|
|
3
17
|
## 0.12.9
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/src/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export { KyselySecretService } from './kysely-secret-service.js';
|
|
|
10
10
|
export type { KyselySecretServiceConfig } from './kysely-secret-service.js';
|
|
11
11
|
export { KyselyCredentialService } from './kysely-credential-service.js';
|
|
12
12
|
export type { KyselyCredentialServiceConfig } from './kysely-credential-service.js';
|
|
13
|
+
export { KyselySessionStore } from './kysely-session-store.js';
|
|
13
14
|
export type { KyselyPikkuDB } from './kysely-tables.js';
|
|
14
15
|
export type { WorkflowRunService } from '@pikku/core/workflow';
|
|
15
16
|
export type { AgentRunService, AgentRunRow } from '@pikku/core/ai-agent';
|
package/dist/src/index.js
CHANGED
|
@@ -8,3 +8,4 @@ export { KyselyAgentRunService } from './kysely-ai-agent-run-service.js';
|
|
|
8
8
|
export { KyselyAIRunStateService } from './kysely-ai-run-state-service.js';
|
|
9
9
|
export { KyselySecretService } from './kysely-secret-service.js';
|
|
10
10
|
export { KyselyCredentialService } from './kysely-credential-service.js';
|
|
11
|
+
export { KyselySessionStore } from './kysely-session-store.js';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CoreUserSession } from '@pikku/core';
|
|
2
1
|
import type { Channel } from '@pikku/core/channel';
|
|
3
2
|
import { ChannelStore } from '@pikku/core/channel';
|
|
4
3
|
import type { Kysely } from 'kysely';
|
|
@@ -10,9 +9,9 @@ export declare class KyselyChannelStore extends ChannelStore {
|
|
|
10
9
|
init(): Promise<void>;
|
|
11
10
|
addChannel({ channelId, channelName, openingData, }: Channel): Promise<void>;
|
|
12
11
|
removeChannels(channelIds: string[]): Promise<void>;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
setPikkuUserId(channelId: string, pikkuUserId: string | null): Promise<void>;
|
|
13
|
+
getChannel(channelId: string): Promise<Channel & {
|
|
14
|
+
pikkuUserId?: string;
|
|
16
15
|
}>;
|
|
17
16
|
close(): Promise<void>;
|
|
18
17
|
}
|
|
@@ -19,7 +19,7 @@ export class KyselyChannelStore extends ChannelStore {
|
|
|
19
19
|
.addColumn('channel_name', 'text', (col) => col.notNull())
|
|
20
20
|
.addColumn('created_at', 'timestamp', (col) => col.defaultTo(sql `CURRENT_TIMESTAMP`).notNull())
|
|
21
21
|
.addColumn('opening_data', 'text', (col) => col.notNull().defaultTo('{}'))
|
|
22
|
-
.addColumn('
|
|
22
|
+
.addColumn('pikku_user_id', 'text')
|
|
23
23
|
.addColumn('last_wire', 'timestamp', (col) => col.defaultTo(sql `CURRENT_TIMESTAMP`).notNull())
|
|
24
24
|
.execute();
|
|
25
25
|
await this.db.schema
|
|
@@ -53,17 +53,17 @@ export class KyselyChannelStore extends ChannelStore {
|
|
|
53
53
|
.where('channelId', 'in', channelIds)
|
|
54
54
|
.execute();
|
|
55
55
|
}
|
|
56
|
-
async
|
|
56
|
+
async setPikkuUserId(channelId, pikkuUserId) {
|
|
57
57
|
await this.db
|
|
58
58
|
.updateTable('channels')
|
|
59
|
-
.set({
|
|
59
|
+
.set({ pikkuUserId })
|
|
60
60
|
.where('channelId', '=', channelId)
|
|
61
61
|
.execute();
|
|
62
62
|
}
|
|
63
|
-
async
|
|
63
|
+
async getChannel(channelId) {
|
|
64
64
|
const row = await this.db
|
|
65
65
|
.selectFrom('channels')
|
|
66
|
-
.select(['channelId', 'channelName', 'openingData', '
|
|
66
|
+
.select(['channelId', 'channelName', 'openingData', 'pikkuUserId'])
|
|
67
67
|
.where('channelId', '=', channelId)
|
|
68
68
|
.executeTakeFirst();
|
|
69
69
|
if (!row) {
|
|
@@ -73,7 +73,7 @@ export class KyselyChannelStore extends ChannelStore {
|
|
|
73
73
|
channelId: row.channelId,
|
|
74
74
|
channelName: row.channelName,
|
|
75
75
|
openingData: parseJson(row.openingData) ?? {},
|
|
76
|
-
|
|
76
|
+
pikkuUserId: row.pikkuUserId ?? undefined,
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
79
|
async close() { }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CoreUserSession } from '@pikku/core';
|
|
2
|
+
import type { SessionStore } from '@pikku/core/services';
|
|
3
|
+
import type { Kysely } from 'kysely';
|
|
4
|
+
import type { KyselyPikkuDB } from './kysely-tables.js';
|
|
5
|
+
export declare class KyselySessionStore implements SessionStore {
|
|
6
|
+
private db;
|
|
7
|
+
private initialized;
|
|
8
|
+
constructor(db: Kysely<KyselyPikkuDB>);
|
|
9
|
+
init(): Promise<void>;
|
|
10
|
+
get(pikkuUserId: string): Promise<CoreUserSession | undefined>;
|
|
11
|
+
set(pikkuUserId: string, session: CoreUserSession): Promise<void>;
|
|
12
|
+
clear(pikkuUserId: string): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { sql } from 'kysely';
|
|
2
|
+
import { parseJson } from './kysely-json.js';
|
|
3
|
+
export class KyselySessionStore {
|
|
4
|
+
db;
|
|
5
|
+
initialized = false;
|
|
6
|
+
constructor(db) {
|
|
7
|
+
this.db = db;
|
|
8
|
+
}
|
|
9
|
+
async init() {
|
|
10
|
+
if (this.initialized) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
await this.db.schema
|
|
14
|
+
.createTable('pikku_user_sessions')
|
|
15
|
+
.ifNotExists()
|
|
16
|
+
.addColumn('pikku_user_id', 'text', (col) => col.primaryKey())
|
|
17
|
+
.addColumn('session', 'text', (col) => col.notNull())
|
|
18
|
+
.addColumn('created_at', 'timestamp', (col) => col.defaultTo(sql `CURRENT_TIMESTAMP`).notNull())
|
|
19
|
+
.addColumn('updated_at', 'timestamp', (col) => col.defaultTo(sql `CURRENT_TIMESTAMP`).notNull())
|
|
20
|
+
.execute();
|
|
21
|
+
this.initialized = true;
|
|
22
|
+
}
|
|
23
|
+
async get(pikkuUserId) {
|
|
24
|
+
const row = await this.db
|
|
25
|
+
.selectFrom('pikkuUserSessions')
|
|
26
|
+
.select(['session'])
|
|
27
|
+
.where('pikkuUserId', '=', pikkuUserId)
|
|
28
|
+
.executeTakeFirst();
|
|
29
|
+
if (!row) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return (parseJson(row.session) ?? undefined);
|
|
33
|
+
}
|
|
34
|
+
async set(pikkuUserId, session) {
|
|
35
|
+
await this.db
|
|
36
|
+
.insertInto('pikkuUserSessions')
|
|
37
|
+
.values({
|
|
38
|
+
pikkuUserId,
|
|
39
|
+
session: JSON.stringify(session),
|
|
40
|
+
updatedAt: new Date(),
|
|
41
|
+
})
|
|
42
|
+
.onConflict((oc) => oc.column('pikkuUserId').doUpdateSet({
|
|
43
|
+
session: JSON.stringify(session),
|
|
44
|
+
updatedAt: new Date(),
|
|
45
|
+
}))
|
|
46
|
+
.execute();
|
|
47
|
+
}
|
|
48
|
+
async clear(pikkuUserId) {
|
|
49
|
+
await this.db
|
|
50
|
+
.deleteFrom('pikkuUserSessions')
|
|
51
|
+
.where('pikkuUserId', '=', pikkuUserId)
|
|
52
|
+
.execute();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -5,7 +5,7 @@ export interface ChannelsTable {
|
|
|
5
5
|
channelName: string;
|
|
6
6
|
createdAt: Generated<Date>;
|
|
7
7
|
openingData: string;
|
|
8
|
-
|
|
8
|
+
pikkuUserId: string | null;
|
|
9
9
|
lastWire: Generated<Date>;
|
|
10
10
|
}
|
|
11
11
|
export interface ChannelSubscriptionsTable {
|
|
@@ -153,6 +153,12 @@ export interface CredentialsAuditTable {
|
|
|
153
153
|
action: string;
|
|
154
154
|
performedAt: Generated<Date>;
|
|
155
155
|
}
|
|
156
|
+
export interface UserSessionsTable {
|
|
157
|
+
pikkuUserId: string;
|
|
158
|
+
session: string;
|
|
159
|
+
createdAt: Generated<Date>;
|
|
160
|
+
updatedAt: Generated<Date>;
|
|
161
|
+
}
|
|
156
162
|
export interface KyselyPikkuDB {
|
|
157
163
|
channels: ChannelsTable;
|
|
158
164
|
channelSubscriptions: ChannelSubscriptionsTable;
|
|
@@ -171,4 +177,5 @@ export interface KyselyPikkuDB {
|
|
|
171
177
|
secretsAudit: SecretsAuditTable;
|
|
172
178
|
credentials: CredentialsTable;
|
|
173
179
|
credentialsAudit: CredentialsAuditTable;
|
|
180
|
+
pikkuUserSessions: UserSessionsTable;
|
|
174
181
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.ts","../src/kysely-ai-agent-run-service.ts","../src/kysely-ai-run-state-service.ts","../src/kysely-ai-storage-service.ts","../src/kysely-channel-store.ts","../src/kysely-credential-service.ts","../src/kysely-deployment-service.ts","../src/kysely-eventhub-store.ts","../src/kysely-json.ts","../src/kysely-secret-service.ts","../src/kysely-tables.ts","../src/kysely-workflow-run-service.ts","../src/kysely-workflow-service.ts","../bin/pikku-kysely-pure.ts"],"version":"5.9.3"}
|
|
1
|
+
{"root":["../src/index.ts","../src/kysely-ai-agent-run-service.ts","../src/kysely-ai-run-state-service.ts","../src/kysely-ai-storage-service.ts","../src/kysely-channel-store.ts","../src/kysely-credential-service.ts","../src/kysely-deployment-service.ts","../src/kysely-eventhub-store.ts","../src/kysely-json.ts","../src/kysely-secret-service.ts","../src/kysely-session-store.ts","../src/kysely-tables.ts","../src/kysely-workflow-run-service.ts","../src/kysely-workflow-service.ts","../bin/pikku-kysely-pure.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/kysely",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.10",
|
|
4
4
|
"author": "yasser.fadl@gmail.com",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"module": "dist/src/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"prepublishOnly": "yarn build"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@pikku/core": "^0.12.
|
|
23
|
+
"@pikku/core": "^0.12.18"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"kysely": "^0.28.12"
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ export { KyselySecretService } from './kysely-secret-service.js'
|
|
|
10
10
|
export type { KyselySecretServiceConfig } from './kysely-secret-service.js'
|
|
11
11
|
export { KyselyCredentialService } from './kysely-credential-service.js'
|
|
12
12
|
export type { KyselyCredentialServiceConfig } from './kysely-credential-service.js'
|
|
13
|
+
export { KyselySessionStore } from './kysely-session-store.js'
|
|
13
14
|
|
|
14
15
|
export type { KyselyPikkuDB } from './kysely-tables.js'
|
|
15
16
|
export type { WorkflowRunService } from '@pikku/core/workflow'
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CoreUserSession } from '@pikku/core'
|
|
2
1
|
import type { Channel } from '@pikku/core/channel'
|
|
3
2
|
import { ChannelStore } from '@pikku/core/channel'
|
|
4
3
|
import type { Kysely } from 'kysely'
|
|
@@ -27,7 +26,7 @@ export class KyselyChannelStore extends ChannelStore {
|
|
|
27
26
|
col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
28
27
|
)
|
|
29
28
|
.addColumn('opening_data', 'text', (col) => col.notNull().defaultTo('{}'))
|
|
30
|
-
.addColumn('
|
|
29
|
+
.addColumn('pikku_user_id', 'text')
|
|
31
30
|
.addColumn('last_wire', 'timestamp', (col) =>
|
|
32
31
|
col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
33
32
|
)
|
|
@@ -75,23 +74,23 @@ export class KyselyChannelStore extends ChannelStore {
|
|
|
75
74
|
.execute()
|
|
76
75
|
}
|
|
77
76
|
|
|
78
|
-
public async
|
|
77
|
+
public async setPikkuUserId(
|
|
79
78
|
channelId: string,
|
|
80
|
-
|
|
79
|
+
pikkuUserId: string | null
|
|
81
80
|
): Promise<void> {
|
|
82
81
|
await this.db
|
|
83
82
|
.updateTable('channels')
|
|
84
|
-
.set({
|
|
83
|
+
.set({ pikkuUserId })
|
|
85
84
|
.where('channelId', '=', channelId)
|
|
86
85
|
.execute()
|
|
87
86
|
}
|
|
88
87
|
|
|
89
|
-
public async
|
|
88
|
+
public async getChannel(
|
|
90
89
|
channelId: string
|
|
91
|
-
): Promise<Channel & {
|
|
90
|
+
): Promise<Channel & { pikkuUserId?: string }> {
|
|
92
91
|
const row = await this.db
|
|
93
92
|
.selectFrom('channels')
|
|
94
|
-
.select(['channelId', 'channelName', 'openingData', '
|
|
93
|
+
.select(['channelId', 'channelName', 'openingData', 'pikkuUserId'])
|
|
95
94
|
.where('channelId', '=', channelId)
|
|
96
95
|
.executeTakeFirst()
|
|
97
96
|
|
|
@@ -103,7 +102,7 @@ export class KyselyChannelStore extends ChannelStore {
|
|
|
103
102
|
channelId: row.channelId,
|
|
104
103
|
channelName: row.channelName,
|
|
105
104
|
openingData: parseJson(row.openingData) ?? {},
|
|
106
|
-
|
|
105
|
+
pikkuUserId: row.pikkuUserId ?? undefined,
|
|
107
106
|
}
|
|
108
107
|
}
|
|
109
108
|
|
|
@@ -17,6 +17,7 @@ import { KyselyAIStorageService } from './kysely-ai-storage-service.js'
|
|
|
17
17
|
import { KyselyAgentRunService } from './kysely-ai-agent-run-service.js'
|
|
18
18
|
import { KyselySecretService } from './kysely-secret-service.js'
|
|
19
19
|
import { KyselyCredentialService } from './kysely-credential-service.js'
|
|
20
|
+
import { KyselySessionStore } from './kysely-session-store.js'
|
|
20
21
|
|
|
21
22
|
function createSqliteDb(): Kysely<KyselyPikkuDB> {
|
|
22
23
|
return new Kysely<KyselyPikkuDB>({
|
|
@@ -109,6 +110,11 @@ function registerTests(
|
|
|
109
110
|
await s.init()
|
|
110
111
|
return s
|
|
111
112
|
},
|
|
113
|
+
sessionStore: async () => {
|
|
114
|
+
const s = new KyselySessionStore(getDb())
|
|
115
|
+
await s.init()
|
|
116
|
+
return s
|
|
117
|
+
},
|
|
112
118
|
},
|
|
113
119
|
})
|
|
114
120
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { CoreUserSession } from '@pikku/core'
|
|
2
|
+
import type { SessionStore } from '@pikku/core/services'
|
|
3
|
+
import type { Kysely } from 'kysely'
|
|
4
|
+
import { sql } from 'kysely'
|
|
5
|
+
import type { KyselyPikkuDB } from './kysely-tables.js'
|
|
6
|
+
import { parseJson } from './kysely-json.js'
|
|
7
|
+
|
|
8
|
+
export class KyselySessionStore implements SessionStore {
|
|
9
|
+
private initialized = false
|
|
10
|
+
|
|
11
|
+
constructor(private db: Kysely<KyselyPikkuDB>) {}
|
|
12
|
+
|
|
13
|
+
public async init(): Promise<void> {
|
|
14
|
+
if (this.initialized) {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
await this.db.schema
|
|
19
|
+
.createTable('pikku_user_sessions')
|
|
20
|
+
.ifNotExists()
|
|
21
|
+
.addColumn('pikku_user_id', 'text', (col) => col.primaryKey())
|
|
22
|
+
.addColumn('session', 'text', (col) => col.notNull())
|
|
23
|
+
.addColumn('created_at', 'timestamp', (col) =>
|
|
24
|
+
col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
25
|
+
)
|
|
26
|
+
.addColumn('updated_at', 'timestamp', (col) =>
|
|
27
|
+
col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
|
|
28
|
+
)
|
|
29
|
+
.execute()
|
|
30
|
+
|
|
31
|
+
this.initialized = true
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async get(pikkuUserId: string): Promise<CoreUserSession | undefined> {
|
|
35
|
+
const row = await this.db
|
|
36
|
+
.selectFrom('pikkuUserSessions')
|
|
37
|
+
.select(['session'])
|
|
38
|
+
.where('pikkuUserId', '=', pikkuUserId)
|
|
39
|
+
.executeTakeFirst()
|
|
40
|
+
|
|
41
|
+
if (!row) {
|
|
42
|
+
return undefined
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (parseJson(row.session) ?? undefined) as
|
|
46
|
+
| CoreUserSession
|
|
47
|
+
| undefined
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async set(pikkuUserId: string, session: CoreUserSession): Promise<void> {
|
|
51
|
+
await this.db
|
|
52
|
+
.insertInto('pikkuUserSessions')
|
|
53
|
+
.values({
|
|
54
|
+
pikkuUserId,
|
|
55
|
+
session: JSON.stringify(session),
|
|
56
|
+
updatedAt: new Date(),
|
|
57
|
+
})
|
|
58
|
+
.onConflict((oc) =>
|
|
59
|
+
oc.column('pikkuUserId').doUpdateSet({
|
|
60
|
+
session: JSON.stringify(session),
|
|
61
|
+
updatedAt: new Date(),
|
|
62
|
+
})
|
|
63
|
+
)
|
|
64
|
+
.execute()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async clear(pikkuUserId: string): Promise<void> {
|
|
68
|
+
await this.db
|
|
69
|
+
.deleteFrom('pikkuUserSessions')
|
|
70
|
+
.where('pikkuUserId', '=', pikkuUserId)
|
|
71
|
+
.execute()
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/kysely-tables.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface ChannelsTable {
|
|
|
10
10
|
channelName: string
|
|
11
11
|
createdAt: Generated<Date>
|
|
12
12
|
openingData: string
|
|
13
|
-
|
|
13
|
+
pikkuUserId: string | null
|
|
14
14
|
lastWire: Generated<Date>
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -175,6 +175,13 @@ export interface CredentialsAuditTable {
|
|
|
175
175
|
performedAt: Generated<Date>
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
export interface UserSessionsTable {
|
|
179
|
+
pikkuUserId: string
|
|
180
|
+
session: string
|
|
181
|
+
createdAt: Generated<Date>
|
|
182
|
+
updatedAt: Generated<Date>
|
|
183
|
+
}
|
|
184
|
+
|
|
178
185
|
export interface KyselyPikkuDB {
|
|
179
186
|
channels: ChannelsTable
|
|
180
187
|
channelSubscriptions: ChannelSubscriptionsTable
|
|
@@ -193,4 +200,5 @@ export interface KyselyPikkuDB {
|
|
|
193
200
|
secretsAudit: SecretsAuditTable
|
|
194
201
|
credentials: CredentialsTable
|
|
195
202
|
credentialsAudit: CredentialsAuditTable
|
|
203
|
+
pikkuUserSessions: UserSessionsTable
|
|
196
204
|
}
|