@absolutejs/artifacts 0.0.5 → 0.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 +21 -0
- package/dist/drizzle.js +245 -0
- package/dist/manifest.js +60 -10
- package/dist/manifest.json +59 -6
- package/dist/src/drizzle.d.ts +1586 -0
- package/package.json +16 -4
package/README.md
CHANGED
|
@@ -87,6 +87,27 @@ const history = await artifacts.listRevisions("owner-123", page.id);
|
|
|
87
87
|
const restored = await artifacts.restore("owner-123", page.id, 1);
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
## Production persistence
|
|
91
|
+
|
|
92
|
+
Use the package-owned Drizzle schema on PostgreSQL, including Neon. The store
|
|
93
|
+
atomically writes the current artifact, immutable revision, and lifecycle
|
|
94
|
+
outbox events. It also persists per-revision indexing state and fences every
|
|
95
|
+
artifact read and mutation by owner.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import {
|
|
99
|
+
artifactDrizzleSchema,
|
|
100
|
+
createDrizzleArtifactStore,
|
|
101
|
+
} from "@absolutejs/artifacts/drizzle";
|
|
102
|
+
|
|
103
|
+
const store = createDrizzleArtifactStore({ db });
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Export `artifactDrizzleSchema` from your application's Drizzle schema so its
|
|
107
|
+
normal migration workflow owns the four tables. Insert and select TypeBoxes
|
|
108
|
+
generated directly from those tables are exported from the same entry point;
|
|
109
|
+
hosts should reuse them instead of redefining database row schemas.
|
|
110
|
+
|
|
90
111
|
## File-backed artifact kinds
|
|
91
112
|
|
|
92
113
|
Use the bundled definitions directly or compose them with application-specific
|
package/dist/drizzle.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/drizzle.ts
|
|
3
|
+
import { and, asc, desc, eq, isNotNull, isNull } from "drizzle-orm";
|
|
4
|
+
import {
|
|
5
|
+
customType,
|
|
6
|
+
index,
|
|
7
|
+
integer,
|
|
8
|
+
pgTable,
|
|
9
|
+
primaryKey,
|
|
10
|
+
text,
|
|
11
|
+
timestamp
|
|
12
|
+
} from "drizzle-orm/pg-core";
|
|
13
|
+
import { createInsertSchema, createSelectSchema } from "drizzle-typebox";
|
|
14
|
+
var recordJsonb = customType({
|
|
15
|
+
dataType: () => "jsonb",
|
|
16
|
+
fromDriver: (value) => typeof value === "string" ? JSON.parse(value) : value,
|
|
17
|
+
toDriver: (value) => JSON.stringify(value)
|
|
18
|
+
});
|
|
19
|
+
var revisionJsonb = customType({
|
|
20
|
+
dataType: () => "jsonb",
|
|
21
|
+
fromDriver: (value) => typeof value === "string" ? JSON.parse(value) : value,
|
|
22
|
+
toDriver: (value) => JSON.stringify(value)
|
|
23
|
+
});
|
|
24
|
+
var eventJsonb = customType({
|
|
25
|
+
dataType: () => "jsonb",
|
|
26
|
+
fromDriver: (value) => typeof value === "string" ? JSON.parse(value) : value,
|
|
27
|
+
toDriver: (value) => JSON.stringify(value)
|
|
28
|
+
});
|
|
29
|
+
var indexingJsonb = customType({
|
|
30
|
+
dataType: () => "jsonb",
|
|
31
|
+
fromDriver: (value) => typeof value === "string" ? JSON.parse(value) : value,
|
|
32
|
+
toDriver: (value) => JSON.stringify(value)
|
|
33
|
+
});
|
|
34
|
+
var artifactRecords = pgTable("artifact_records", {
|
|
35
|
+
document: recordJsonb().notNull(),
|
|
36
|
+
id: text().primaryKey(),
|
|
37
|
+
kind: text().notNull(),
|
|
38
|
+
ownerId: text("owner_id").notNull(),
|
|
39
|
+
revision: integer().notNull(),
|
|
40
|
+
status: text().notNull(),
|
|
41
|
+
updatedAt: timestamp("updated_at", {
|
|
42
|
+
mode: "string",
|
|
43
|
+
withTimezone: true
|
|
44
|
+
}).notNull()
|
|
45
|
+
}, (table) => [
|
|
46
|
+
index("artifact_records_owner_updated_idx").on(table.ownerId, table.updatedAt.desc()),
|
|
47
|
+
index("artifact_records_owner_kind_idx").on(table.ownerId, table.kind)
|
|
48
|
+
]);
|
|
49
|
+
var artifactRevisions = pgTable("artifact_revisions", {
|
|
50
|
+
artifactId: text("artifact_id").notNull().references(() => artifactRecords.id),
|
|
51
|
+
document: revisionJsonb().notNull(),
|
|
52
|
+
ownerId: text("owner_id").notNull(),
|
|
53
|
+
revision: integer().notNull()
|
|
54
|
+
}, (table) => [
|
|
55
|
+
primaryKey({
|
|
56
|
+
columns: [table.artifactId, table.revision],
|
|
57
|
+
name: "artifact_revisions_pkey"
|
|
58
|
+
}),
|
|
59
|
+
index("artifact_revisions_owner_idx").on(table.ownerId, table.artifactId, table.revision.desc())
|
|
60
|
+
]);
|
|
61
|
+
var artifactEvents = pgTable("artifact_events", {
|
|
62
|
+
artifactId: text("artifact_id").notNull().references(() => artifactRecords.id),
|
|
63
|
+
createdAt: timestamp("created_at", {
|
|
64
|
+
mode: "string",
|
|
65
|
+
withTimezone: true
|
|
66
|
+
}).notNull(),
|
|
67
|
+
document: eventJsonb().notNull(),
|
|
68
|
+
id: text().primaryKey(),
|
|
69
|
+
ownerId: text("owner_id").notNull(),
|
|
70
|
+
processedAt: timestamp("processed_at", {
|
|
71
|
+
mode: "string",
|
|
72
|
+
withTimezone: true
|
|
73
|
+
}),
|
|
74
|
+
type: text().notNull()
|
|
75
|
+
}, (table) => [
|
|
76
|
+
index("artifact_events_outbox_idx").on(table.processedAt, table.createdAt),
|
|
77
|
+
index("artifact_events_artifact_idx").on(table.ownerId, table.artifactId, table.createdAt)
|
|
78
|
+
]);
|
|
79
|
+
var artifactIndexingStates = pgTable("artifact_indexing_states", {
|
|
80
|
+
artifactId: text("artifact_id").primaryKey().references(() => artifactRecords.id),
|
|
81
|
+
document: indexingJsonb().notNull(),
|
|
82
|
+
ownerId: text("owner_id").notNull(),
|
|
83
|
+
revision: integer().notNull(),
|
|
84
|
+
status: text().notNull(),
|
|
85
|
+
updatedAt: timestamp("updated_at", {
|
|
86
|
+
mode: "string",
|
|
87
|
+
withTimezone: true
|
|
88
|
+
}).notNull()
|
|
89
|
+
});
|
|
90
|
+
var artifactDrizzleSchema = {
|
|
91
|
+
artifactEvents,
|
|
92
|
+
artifactIndexingStates,
|
|
93
|
+
artifactRecords,
|
|
94
|
+
artifactRevisions
|
|
95
|
+
};
|
|
96
|
+
var ArtifactRecordInsertSchema = createInsertSchema(artifactRecords);
|
|
97
|
+
var ArtifactRecordSelectSchema = createSelectSchema(artifactRecords);
|
|
98
|
+
var ArtifactRevisionInsertSchema = createInsertSchema(artifactRevisions);
|
|
99
|
+
var ArtifactRevisionSelectSchema = createSelectSchema(artifactRevisions);
|
|
100
|
+
var ArtifactEventInsertSchema = createInsertSchema(artifactEvents);
|
|
101
|
+
var ArtifactEventSelectSchema = createSelectSchema(artifactEvents);
|
|
102
|
+
var ArtifactIndexingStateInsertSchema = createInsertSchema(artifactIndexingStates);
|
|
103
|
+
var ArtifactIndexingStateSelectSchema = createSelectSchema(artifactIndexingStates);
|
|
104
|
+
var eventRows = (events) => events.map((event) => ({
|
|
105
|
+
artifactId: event.artifactId,
|
|
106
|
+
createdAt: event.createdAt,
|
|
107
|
+
document: event,
|
|
108
|
+
id: event.id,
|
|
109
|
+
ownerId: event.ownerId,
|
|
110
|
+
processedAt: event.processedAt,
|
|
111
|
+
type: event.type
|
|
112
|
+
}));
|
|
113
|
+
var assertEventsBelongToArtifact = (record, events) => {
|
|
114
|
+
if (events.some((event) => event.artifactId !== record.id || event.ownerId !== record.ownerId))
|
|
115
|
+
throw new Error("Artifact events must belong to the persisted artifact");
|
|
116
|
+
};
|
|
117
|
+
var recordRow = (record) => ({
|
|
118
|
+
document: record,
|
|
119
|
+
id: record.id,
|
|
120
|
+
kind: record.kind,
|
|
121
|
+
ownerId: record.ownerId,
|
|
122
|
+
revision: record.revision,
|
|
123
|
+
status: record.status,
|
|
124
|
+
updatedAt: record.updatedAt
|
|
125
|
+
});
|
|
126
|
+
var recordUpdate = (record) => ({
|
|
127
|
+
document: record,
|
|
128
|
+
kind: record.kind,
|
|
129
|
+
ownerId: record.ownerId,
|
|
130
|
+
revision: record.revision,
|
|
131
|
+
status: record.status,
|
|
132
|
+
updatedAt: record.updatedAt
|
|
133
|
+
});
|
|
134
|
+
var revisionRow = (record) => ({
|
|
135
|
+
artifactId: record.id,
|
|
136
|
+
document: record,
|
|
137
|
+
ownerId: record.ownerId,
|
|
138
|
+
revision: record.revision
|
|
139
|
+
});
|
|
140
|
+
var createDrizzleArtifactStore = (options) => ({
|
|
141
|
+
create: (record, events = []) => options.db.transaction(async (transaction) => {
|
|
142
|
+
assertEventsBelongToArtifact(record, events);
|
|
143
|
+
await transaction.insert(artifactRecords).values(recordRow(record));
|
|
144
|
+
await transaction.insert(artifactRevisions).values(revisionRow(record));
|
|
145
|
+
if (events.length > 0)
|
|
146
|
+
await transaction.insert(artifactEvents).values(eventRows(events));
|
|
147
|
+
}),
|
|
148
|
+
get: async (ownerId, artifactId) => {
|
|
149
|
+
const [row] = await options.db.select({ document: artifactRecords.document }).from(artifactRecords).where(and(eq(artifactRecords.id, artifactId), eq(artifactRecords.ownerId, ownerId))).limit(1);
|
|
150
|
+
return row?.document ?? null;
|
|
151
|
+
},
|
|
152
|
+
getIndexingState: async (ownerId, artifactId) => {
|
|
153
|
+
const [row] = await options.db.select({ document: artifactIndexingStates.document }).from(artifactIndexingStates).where(and(eq(artifactIndexingStates.artifactId, artifactId), eq(artifactIndexingStates.ownerId, ownerId))).limit(1);
|
|
154
|
+
return row?.document ?? null;
|
|
155
|
+
},
|
|
156
|
+
getRevision: async (ownerId, artifactId, revision) => {
|
|
157
|
+
const [row] = await options.db.select({ document: artifactRevisions.document }).from(artifactRevisions).where(and(eq(artifactRevisions.artifactId, artifactId), eq(artifactRevisions.ownerId, ownerId), eq(artifactRevisions.revision, revision))).limit(1);
|
|
158
|
+
return row?.document ?? null;
|
|
159
|
+
},
|
|
160
|
+
list: async (ownerId, query = {}) => {
|
|
161
|
+
const conditions = [eq(artifactRecords.ownerId, ownerId)];
|
|
162
|
+
if (query.kind)
|
|
163
|
+
conditions.push(eq(artifactRecords.kind, query.kind));
|
|
164
|
+
if (query.status)
|
|
165
|
+
conditions.push(eq(artifactRecords.status, query.status));
|
|
166
|
+
const statement = options.db.select({ document: artifactRecords.document }).from(artifactRecords).where(and(...conditions)).orderBy(desc(artifactRecords.updatedAt));
|
|
167
|
+
const rows = query.limit === undefined ? await statement : await statement.limit(query.limit);
|
|
168
|
+
return rows.map(({ document }) => document);
|
|
169
|
+
},
|
|
170
|
+
listEvents: async (query = {}) => {
|
|
171
|
+
const conditions = [];
|
|
172
|
+
if (query.processed !== undefined)
|
|
173
|
+
conditions.push(query.processed ? isNotNull(artifactEvents.processedAt) : isNull(artifactEvents.processedAt));
|
|
174
|
+
if (query.type)
|
|
175
|
+
conditions.push(eq(artifactEvents.type, query.type));
|
|
176
|
+
const statement = options.db.select({
|
|
177
|
+
document: artifactEvents.document,
|
|
178
|
+
processedAt: artifactEvents.processedAt
|
|
179
|
+
}).from(artifactEvents).where(conditions.length > 0 ? and(...conditions) : undefined).orderBy(asc(artifactEvents.createdAt));
|
|
180
|
+
const rows = query.limit === undefined ? await statement : await statement.limit(query.limit);
|
|
181
|
+
return rows.map(({ document, processedAt }) => ({
|
|
182
|
+
...document,
|
|
183
|
+
...processedAt ? { processedAt: new Date(processedAt).toISOString() } : {}
|
|
184
|
+
}));
|
|
185
|
+
},
|
|
186
|
+
listReferencedAssetIds: async () => {
|
|
187
|
+
const rows = await options.db.select({ document: artifactRevisions.document }).from(artifactRevisions);
|
|
188
|
+
return [
|
|
189
|
+
...new Set(rows.flatMap(({ document }) => document.assets.map(({ id }) => id)))
|
|
190
|
+
];
|
|
191
|
+
},
|
|
192
|
+
listRevisions: async (ownerId, artifactId) => (await options.db.select({ document: artifactRevisions.document }).from(artifactRevisions).where(and(eq(artifactRevisions.artifactId, artifactId), eq(artifactRevisions.ownerId, ownerId))).orderBy(desc(artifactRevisions.revision))).map(({ document }) => document),
|
|
193
|
+
markEventProcessed: async (eventId, processedAt) => (await options.db.update(artifactEvents).set({ processedAt }).where(eq(artifactEvents.id, eventId)).returning({ id: artifactEvents.id })).length === 1,
|
|
194
|
+
putIndexingState: (ownerId, state, events = []) => options.db.transaction(async (transaction) => {
|
|
195
|
+
assertEventsBelongToArtifact({ id: state.artifactId, ownerId }, events);
|
|
196
|
+
const [artifact] = await transaction.select({ id: artifactRecords.id }).from(artifactRecords).where(and(eq(artifactRecords.id, state.artifactId), eq(artifactRecords.ownerId, ownerId))).limit(1);
|
|
197
|
+
if (!artifact)
|
|
198
|
+
throw new Error("Artifact not found");
|
|
199
|
+
await transaction.insert(artifactIndexingStates).values({
|
|
200
|
+
artifactId: state.artifactId,
|
|
201
|
+
document: state,
|
|
202
|
+
ownerId,
|
|
203
|
+
revision: state.revision,
|
|
204
|
+
status: state.status,
|
|
205
|
+
updatedAt: state.updatedAt
|
|
206
|
+
}).onConflictDoUpdate({
|
|
207
|
+
set: {
|
|
208
|
+
document: state,
|
|
209
|
+
ownerId,
|
|
210
|
+
revision: state.revision,
|
|
211
|
+
status: state.status,
|
|
212
|
+
updatedAt: state.updatedAt
|
|
213
|
+
},
|
|
214
|
+
target: artifactIndexingStates.artifactId
|
|
215
|
+
});
|
|
216
|
+
if (events.length > 0)
|
|
217
|
+
await transaction.insert(artifactEvents).values(eventRows(events));
|
|
218
|
+
}),
|
|
219
|
+
save: (record, expectedRevision, events = []) => options.db.transaction(async (transaction) => {
|
|
220
|
+
assertEventsBelongToArtifact(record, events);
|
|
221
|
+
const updated = await transaction.update(artifactRecords).set(recordUpdate(record)).where(and(eq(artifactRecords.id, record.id), eq(artifactRecords.ownerId, record.ownerId), eq(artifactRecords.revision, expectedRevision))).returning({ id: artifactRecords.id });
|
|
222
|
+
if (updated.length !== 1)
|
|
223
|
+
return false;
|
|
224
|
+
await transaction.insert(artifactRevisions).values(revisionRow(record));
|
|
225
|
+
if (events.length > 0)
|
|
226
|
+
await transaction.insert(artifactEvents).values(eventRows(events));
|
|
227
|
+
return true;
|
|
228
|
+
})
|
|
229
|
+
});
|
|
230
|
+
export {
|
|
231
|
+
createDrizzleArtifactStore,
|
|
232
|
+
artifactRevisions,
|
|
233
|
+
artifactRecords,
|
|
234
|
+
artifactIndexingStates,
|
|
235
|
+
artifactEvents,
|
|
236
|
+
artifactDrizzleSchema,
|
|
237
|
+
ArtifactRevisionSelectSchema,
|
|
238
|
+
ArtifactRevisionInsertSchema,
|
|
239
|
+
ArtifactRecordSelectSchema,
|
|
240
|
+
ArtifactRecordInsertSchema,
|
|
241
|
+
ArtifactIndexingStateSelectSchema,
|
|
242
|
+
ArtifactIndexingStateInsertSchema,
|
|
243
|
+
ArtifactEventSelectSchema,
|
|
244
|
+
ArtifactEventInsertSchema
|
|
245
|
+
};
|
package/dist/manifest.js
CHANGED
|
@@ -14,6 +14,10 @@ var __export = (target, all) => {
|
|
|
14
14
|
set: __exportSetter.bind(all, name)
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
|
+
var defineImplementation = () => (implementation) => {
|
|
18
|
+
const defined = implementation;
|
|
19
|
+
return defined;
|
|
20
|
+
};
|
|
17
21
|
var defineManifest = () => (manifest) => manifest;
|
|
18
22
|
var literal = (value) => value;
|
|
19
23
|
var RUNTIME_KIND = literal("runtime");
|
|
@@ -5986,13 +5990,63 @@ var manifest = defineManifest()({
|
|
|
5986
5990
|
name: "@absolutejs/artifacts",
|
|
5987
5991
|
tagline: "Give everything your AI makes a real lifecycle."
|
|
5988
5992
|
},
|
|
5993
|
+
implements: [
|
|
5994
|
+
defineImplementation()({
|
|
5995
|
+
contract: "artifacts/store",
|
|
5996
|
+
factory: "createMemoryArtifactStore",
|
|
5997
|
+
from: "@absolutejs/artifacts",
|
|
5998
|
+
title: "In memory (development only \u2014 history resets on restart)",
|
|
5999
|
+
wiring: {
|
|
6000
|
+
code: "createMemoryArtifactStore()",
|
|
6001
|
+
imports: [
|
|
6002
|
+
{
|
|
6003
|
+
from: "@absolutejs/artifacts",
|
|
6004
|
+
names: ["createMemoryArtifactStore"]
|
|
6005
|
+
}
|
|
6006
|
+
]
|
|
6007
|
+
}
|
|
6008
|
+
}),
|
|
6009
|
+
defineImplementation()({
|
|
6010
|
+
contract: "artifacts/store",
|
|
6011
|
+
factory: "createDrizzleArtifactStore",
|
|
6012
|
+
from: "@absolutejs/artifacts/drizzle",
|
|
6013
|
+
requires: {
|
|
6014
|
+
peers: [
|
|
6015
|
+
{
|
|
6016
|
+
name: "drizzle-orm",
|
|
6017
|
+
range: ">=1.0.0-rc.4 <2",
|
|
6018
|
+
reason: "Typed artifact revisions, indexing state, and transactional outbox persistence"
|
|
6019
|
+
}
|
|
6020
|
+
],
|
|
6021
|
+
services: [
|
|
6022
|
+
{
|
|
6023
|
+
description: "Artifact lifecycle and revision database",
|
|
6024
|
+
id: "postgres"
|
|
6025
|
+
}
|
|
6026
|
+
]
|
|
6027
|
+
},
|
|
6028
|
+
title: "Drizzle Postgres (production, including Neon)",
|
|
6029
|
+
wiring: {
|
|
6030
|
+
code: "createDrizzleArtifactStore({ db })",
|
|
6031
|
+
imports: [
|
|
6032
|
+
{
|
|
6033
|
+
from: "@absolutejs/artifacts/drizzle",
|
|
6034
|
+
names: ["createDrizzleArtifactStore"]
|
|
6035
|
+
}
|
|
6036
|
+
]
|
|
6037
|
+
}
|
|
6038
|
+
})
|
|
6039
|
+
],
|
|
5989
6040
|
settings: Type2.Object({}),
|
|
5990
6041
|
slots: {
|
|
5991
|
-
|
|
6042
|
+
store: {
|
|
5992
6043
|
configPath: "$self",
|
|
5993
|
-
contract: "artifacts/
|
|
5994
|
-
description: "
|
|
5995
|
-
known: [
|
|
6044
|
+
contract: "artifacts/store",
|
|
6045
|
+
description: "Where current artifacts, immutable revisions, indexing state, and transactional outbox events live",
|
|
6046
|
+
known: [
|
|
6047
|
+
"@absolutejs/artifacts#createMemoryArtifactStore",
|
|
6048
|
+
"@absolutejs/artifacts#drizzle"
|
|
6049
|
+
],
|
|
5996
6050
|
required: true
|
|
5997
6051
|
}
|
|
5998
6052
|
},
|
|
@@ -6090,7 +6144,7 @@ var manifest = defineManifest()({
|
|
|
6090
6144
|
"\t}",
|
|
6091
6145
|
"});",
|
|
6092
6146
|
"",
|
|
6093
|
-
"const artifactStore =
|
|
6147
|
+
"const artifactStore = ${slot.store};",
|
|
6094
6148
|
"const artifactService = createArtifactService({",
|
|
6095
6149
|
"\tregistry: artifactRegistry,",
|
|
6096
6150
|
"\tstore: artifactStore",
|
|
@@ -6100,11 +6154,7 @@ var manifest = defineManifest()({
|
|
|
6100
6154
|
imports: [
|
|
6101
6155
|
{
|
|
6102
6156
|
from: "@absolutejs/artifacts",
|
|
6103
|
-
names: [
|
|
6104
|
-
"createArtifactService",
|
|
6105
|
-
"createMemoryArtifactStore",
|
|
6106
|
-
"defineArtifactRegistry"
|
|
6107
|
-
]
|
|
6157
|
+
names: ["createArtifactService", "defineArtifactRegistry"]
|
|
6108
6158
|
},
|
|
6109
6159
|
{ from: "@sinclair/typebox", names: ["Type"] }
|
|
6110
6160
|
],
|
package/dist/manifest.json
CHANGED
|
@@ -8,16 +8,70 @@
|
|
|
8
8
|
"name": "@absolutejs/artifacts",
|
|
9
9
|
"tagline": "Give everything your AI makes a real lifecycle."
|
|
10
10
|
},
|
|
11
|
+
"implements": [
|
|
12
|
+
{
|
|
13
|
+
"contract": "artifacts/store",
|
|
14
|
+
"factory": "createMemoryArtifactStore",
|
|
15
|
+
"from": "@absolutejs/artifacts",
|
|
16
|
+
"title": "In memory (development only — history resets on restart)",
|
|
17
|
+
"wiring": {
|
|
18
|
+
"code": "createMemoryArtifactStore()",
|
|
19
|
+
"imports": [
|
|
20
|
+
{
|
|
21
|
+
"from": "@absolutejs/artifacts",
|
|
22
|
+
"names": [
|
|
23
|
+
"createMemoryArtifactStore"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"contract": "artifacts/store",
|
|
31
|
+
"factory": "createDrizzleArtifactStore",
|
|
32
|
+
"from": "@absolutejs/artifacts/drizzle",
|
|
33
|
+
"requires": {
|
|
34
|
+
"peers": [
|
|
35
|
+
{
|
|
36
|
+
"name": "drizzle-orm",
|
|
37
|
+
"range": ">=1.0.0-rc.4 <2",
|
|
38
|
+
"reason": "Typed artifact revisions, indexing state, and transactional outbox persistence"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"services": [
|
|
42
|
+
{
|
|
43
|
+
"description": "Artifact lifecycle and revision database",
|
|
44
|
+
"id": "postgres"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
"title": "Drizzle Postgres (production, including Neon)",
|
|
49
|
+
"wiring": {
|
|
50
|
+
"code": "createDrizzleArtifactStore({ db })",
|
|
51
|
+
"imports": [
|
|
52
|
+
{
|
|
53
|
+
"from": "@absolutejs/artifacts/drizzle",
|
|
54
|
+
"names": [
|
|
55
|
+
"createDrizzleArtifactStore"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
],
|
|
11
62
|
"settings": {
|
|
12
63
|
"type": "object",
|
|
13
64
|
"properties": {}
|
|
14
65
|
},
|
|
15
66
|
"slots": {
|
|
16
|
-
"
|
|
67
|
+
"store": {
|
|
17
68
|
"configPath": "$self",
|
|
18
|
-
"contract": "artifacts/
|
|
19
|
-
"description": "
|
|
20
|
-
"known": [
|
|
69
|
+
"contract": "artifacts/store",
|
|
70
|
+
"description": "Where current artifacts, immutable revisions, indexing state, and transactional outbox events live",
|
|
71
|
+
"known": [
|
|
72
|
+
"@absolutejs/artifacts#createMemoryArtifactStore",
|
|
73
|
+
"@absolutejs/artifacts#drizzle"
|
|
74
|
+
],
|
|
21
75
|
"required": true
|
|
22
76
|
}
|
|
23
77
|
},
|
|
@@ -26,13 +80,12 @@
|
|
|
26
80
|
"description": "Define structured artifact kinds, provide a store, and create the lifecycle service. Add a publisher only when your host supports public access.",
|
|
27
81
|
"id": "default",
|
|
28
82
|
"server": {
|
|
29
|
-
"code": "const artifactRegistry = defineArtifactRegistry({\n\tpage: {\n\t\tcapabilities: ['archive', 'edit', 'preview', 'publish'],\n\t\tcontent: Type.Object({ blocks: Type.Array(Type.Unknown()) }),\n\t\tlabel: 'Page'\n\t}\n});\n\nconst artifactStore =
|
|
83
|
+
"code": "const artifactRegistry = defineArtifactRegistry({\n\tpage: {\n\t\tcapabilities: ['archive', 'edit', 'preview', 'publish'],\n\t\tcontent: Type.Object({ blocks: Type.Array(Type.Unknown()) }),\n\t\tlabel: 'Page'\n\t}\n});\n\nconst artifactStore = ${slot.store};\nconst artifactService = createArtifactService({\n\tregistry: artifactRegistry,\n\tstore: artifactStore\n});",
|
|
30
84
|
"imports": [
|
|
31
85
|
{
|
|
32
86
|
"from": "@absolutejs/artifacts",
|
|
33
87
|
"names": [
|
|
34
88
|
"createArtifactService",
|
|
35
|
-
"createMemoryArtifactStore",
|
|
36
89
|
"defineArtifactRegistry"
|
|
37
90
|
]
|
|
38
91
|
},
|