@@ -32,10 +32,12 @@ export interface MemoryService {
3232 close ( ) : AsyncResult < { } , SystemError > ;
3333 subscribe ( socket : WebSocket ) : AsyncResult < { } , Error > ;
3434 patch ( request : { json ( ) : Promise < any > } ) : Promise < Response > ;
35+ patchJson ( json : In < Transaction > ) : Promise < AsyncResult < any , Error > > ;
3536 query (
3637 request : { json ( ) : Promise < any > } ,
3738 selector : In < { the ?: string ; of ?: string } > ,
3839 ) : Promise < Response > ;
40+ queryJson ( selector : object ) : Promise < AsyncResult < any , Error > > ;
3941}
4042
4143interface MemoryServiceSession {
@@ -50,9 +52,15 @@ class Service implements MemoryService {
5052 patch ( request : { json ( ) : Promise < any > } ) : Promise < Response > {
5153 return patch ( this , request ) ;
5254 }
55+ patchJson ( json : In < Transaction > ) : Promise < AsyncResult < any , Error > > {
56+ return patchJson ( this . router , json ) ;
57+ }
5358 query ( request : { json ( ) : Promise < any > } ) : Promise < Response > {
5459 return query ( this , request ) ;
5560 }
61+ queryJson ( selector : object ) : Promise < AsyncResult < any , Error > > {
62+ return queryJson ( this . router , selector as In < Partial < Selector > > ) ;
63+ }
5664 transact ( transaction : In < Transaction > ) {
5765 return this . router . transact ( transaction ) ;
5866 }
@@ -154,6 +162,9 @@ export const query = async (session: MemoryServiceSession, request: { json(): Pr
154162
155163const parseCommand = ( source : string ) => JSON . parse ( source ) as Command ;
156164
165+ /**
166+ * Converts a raw JSON transaction object into a router transaction
167+ */
157168const asRouterTransaction = ( json : In < Transaction > ) : In < Transaction > =>
158169 Object . fromEntries ( Object . entries ( json ) . map ( ( [ key , value ] ) => [ key , asTransaction ( value ) ] ) ) ;
159170
@@ -166,14 +177,36 @@ const asStatement = <S extends Statement>(statement: S): S => {
166177 if ( statement . cause && typeof statement . cause [ "/" ] === "string" ) {
167178 statement . cause = Reference . fromJSON ( statement . cause as unknown as { "/" : string } ) ;
168179 }
169-
170180 if ( statement . is && ( statement . is as { "/" ?: string } ) [ "/" ] ) {
171181 statement . is = Reference . fromJSON ( statement . is as { "/" : string } ) ;
172182 }
173-
174183 return statement ;
175184} ;
176185
186+ /**
187+ * New library-level patch function that accepts already-parsed JSON
188+ * and returns a plain result for consumers to build HTTP responses as needed.
189+ */
190+ export const patchJson = async (
191+ session : Router . Router ,
192+ json : In < Transaction > ,
193+ ) : Promise < AsyncResult < any , Error > > => {
194+ try {
195+ const transaction = asRouterTransaction ( json ) ;
196+ const result = await session . transact ( transaction ) ;
197+ return result ;
198+ } catch ( cause ) {
199+ const error = cause as Partial < Error > ;
200+ return {
201+ error : {
202+ name : error ?. name ?? "Error" ,
203+ message : error ?. message ?? "Unable to process transaction" ,
204+ stack : error ?. stack ?? "" ,
205+ } ,
206+ } ;
207+ }
208+ } ;
209+
177210const pipeToSocket = async < T > (
178211 stream : ReadableStream < T > ,
179212 socket : WebSocket ,
@@ -188,3 +221,23 @@ const pipeToSocket = async <T>(
188221 return { error : error as Error } ;
189222 }
190223} ;
224+
225+ export const queryJson = async (
226+ session : Router . Router ,
227+ selector : object ,
228+ ) : Promise < AsyncResult < any , Error > > => {
229+ try {
230+ const result = await session . query ( selector as In < Partial < Selector > > ) ;
231+ return result ;
232+ } catch ( cause ) {
233+ console . error ( cause ) ;
234+ const error = cause as Partial < Error > ;
235+ return {
236+ error : {
237+ name : error ?. name ?? "Error" ,
238+ message : error ?. message ?? "Unable to process query" ,
239+ stack : error ?. stack ?? "" ,
240+ } ,
241+ } ;
242+ }
243+ } ;
0 commit comments