From 43f02863a7b6b1c49caba9d343be909ac41b5431 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Tue, 25 Feb 2025 10:53:22 -0700 Subject: [PATCH 1/5] feat: adds API for updating models and updating instances to use them With this change it is now possible to update a model definition in backwards compatible ways. Additionally when creating or updating model instance documents a modelVersion header value can be supplied to indicate that the instance uses the updated version of the model. Instances will always use the init event of a model (i.e. its first version) unless explicitly changed to a new version using the modelVersion header. --- packages/model-client/package.json | 4 +- packages/model-client/src/index.ts | 231 +++++++++++++++++- packages/model-instance-client/src/client.ts | 8 +- packages/model-instance-client/src/events.ts | 19 +- packages/model-instance-client/src/types.ts | 2 + packages/model-instance-client/src/utils.ts | 7 + .../model-instance-client/test/lib.test.ts | 2 +- .../model-instance-protocol/src/codecs.ts | 2 + packages/model-protocol/src/codecs.ts | 87 ++++++- pnpm-lock.yaml | 12 +- tests/c1-integration/test/model.test.ts | 222 +++++++++++++++-- 11 files changed, 566 insertions(+), 30 deletions(-) diff --git a/packages/model-client/package.json b/packages/model-client/package.json index eec3c5b..d847576 100644 --- a/packages/model-client/package.json +++ b/packages/model-client/package.json @@ -33,7 +33,9 @@ "@ceramic-sdk/events": "workspace:^", "@ceramic-sdk/identifiers": "workspace:^", "@ceramic-sdk/model-protocol": "workspace:^", - "@ceramic-sdk/stream-client": "workspace:^" + "@ceramic-sdk/stream-client": "workspace:^", + "@didtools/codecs": "^3.0.0", + "fast-json-patch": "^3.1.1" }, "devDependencies": { "@ceramic-sdk/http-client": "workspace:^", diff --git a/packages/model-client/src/index.ts b/packages/model-client/src/index.ts index 9804a6e..057f834 100644 --- a/packages/model-client/src/index.ts +++ b/packages/model-client/src/index.ts @@ -5,16 +5,22 @@ import { decodeMultibaseToJSON, decodeMultibaseToStreamID, eventToContainer, + signEvent, } from '@ceramic-sdk/events' -import { StreamID } from '@ceramic-sdk/identifiers' +import { CommitID, StreamID } from '@ceramic-sdk/identifiers' import { + type JSONPatchOperation, MODEL, + ModelDataEventPayload, type ModelDefinition, ModelInitEventPayload, + type ModelMetadata, getModelStreamID, } from '@ceramic-sdk/model-protocol' -import { StreamClient } from '@ceramic-sdk/stream-client' +import { StreamClient, type StreamState } from '@ceramic-sdk/stream-client' +import type { DIDString } from '@didtools/codecs' import type { DID } from 'dids' +import jsonpatch from 'fast-json-patch' const header: PartialInitEventHeader = { model: MODEL, sep: 'model' } @@ -38,6 +44,82 @@ export async function createInitEvent( return event } +/** + * Creates a signed data event for a Model stream. + * + * @param params - Parameters required to create the data event. + * @returns A promise that resolves to the signed data event. + * + * @remarks + * The data event updates the content of the stream by applying JSON patch operations + * to the existing content. The resulting event is signed by the controlling DID. + */ +export async function createDataEvent( + params: CreateDataEventParams, +): Promise { + const operations = getPatchOperations( + params.currentContent, + params.newContent, + ) + const payload = createDataEventPayload(params.currentID, operations) + return await signEvent(params.controller, payload) +} + +/** + * Creates a data event payload for a Model stream. + * + * @param current - The current commit ID of the stream. + * @param data - The JSON patch operations to apply to the stream content. + * @param header - Optional header information for the data event. + * @returns A valid data event payload. + * + * @throws Will throw an error if the JSON patch operations are invalid. + */ +export function createDataEventPayload( + current: CommitID, + data: Array, +): ModelDataEventPayload { + const payload: ModelDataEventPayload = { + data, + id: current.baseID.cid, + prev: current.commit, + } + if (!ModelDataEventPayload.is(payload)) { + throw new Error('Invalid payload') + } + return payload +} + +/** + * Computes JSON patch operations to transform one content object into another. + * + * @param fromContent - The current content of the document. + * @param toContent - The new content of the document. + * @returns An array of JSON patch operations required to transform `fromContent` into `toContent`. + * + * @remarks + * - If either `fromContent` or `toContent` is undefined, an empty object `{}` is used as the default. + * - JSON patch operations are generated using the `fast-json-patch` library. + * + * @example + * ```typescript + * const currentContent = { name: 'Alice' }; + * const newContent = { name: 'Bob' }; + * const operations = getPatchOperations(currentContent, newContent); + * console.log(operations); // [{ op: 'replace', path: '/name', value: 'Bob' }] + * ``` + * + * @internal + */ +export function getPatchOperations( + fromContent?: ModelDefinition, + toContent?: ModelDefinition, +): Array { + return jsonpatch.compare( + fromContent ?? {}, + toContent ?? {}, + ) as Array +} /** * Represents a client for interacting with Ceramic models. * @@ -101,6 +183,87 @@ export class ModelClient extends StreamClient { return getModelStreamID(cid) } + /** + * Posts a data event to a model stream and returns its commit ID. + * + * @param params - Parameters for posting the data event. + * @returns A promise that resolves to the `CommitID` of the posted event. + * + * @remarks + * The data event updates the content of a stream and is associated with the + * current state of the stream. + */ + async postDefinition(params: PostDefinitionParams): Promise { + const { controller, ...rest } = params + const event = await createDataEvent({ + ...rest, + controller: this.getDID(controller), + }) + const cid = await this.ceramic.postEventType(SignedEvent, event) + return CommitID.fromStream(params.currentID.baseID, cid) + } + + /** + * Updates a model with a new definition and returns the updated model state. + * Model's can only be updated in backwards compatible ways. + * + * @param params - Parameters for updating the document. + * @returns A promise that resolves to the updated `ModelState`. + * + * @remarks + * This method posts the new content as a data event, updating the document. + * It can optionally take the current document state to avoid re-fetching it. + */ + async updateDefinition( + params: UpdateModelDefinitionParams, + ): Promise { + let currentState: ModelState + let currentId: CommitID + + if (!params.currentState) { + const streamState = await this.getStreamState( + StreamID.fromString(params.streamID), + ) + currentState = this.streamStateToModelState(streamState) + currentId = this.getCurrentID(streamState.event_cid) + } else { + currentState = this.streamStateToModelState(params.currentState) + currentId = this.getCurrentID(params.currentState.event_cid) + } + + const { content } = currentState + const { controller, newContent } = params + + const newCommit = await this.postDefinition({ + controller: this.getDID(controller), + currentContent: content ?? undefined, + newContent, + currentID: currentId, + }) + + return { + commitID: newCommit, + content: newContent, + metadata: { + model: currentState.metadata.model, + controller: currentState.metadata.controller, + ...(typeof currentState.metadata === 'object' + ? currentState.metadata + : {}), + }, + } + } + + /** + * Retrieves the `CommitID` for the provided stream ID. + * + * @param streamID - The stream ID string. + * @returns The `CommitID` for the stream. + */ + getCurrentID(streamID: string): CommitID { + return new CommitID(2, streamID) + } + /** * Retrieves the stringified model stream ID from a model instance document stream ID. * @@ -135,4 +298,68 @@ export class ModelClient extends StreamClient { .content as ModelDefinition return decodedData } + + /** + * Transforms a `StreamState` into a `ModelState`. + * + * @param streamState - The stream state to transform. + * @returns The `ModelState` derived from the stream state. + */ + streamStateToModelState(streamState: StreamState): ModelState { + const streamID = StreamID.fromString(streamState.id) + const decodedData = decodeMultibaseToJSON(streamState.data) + const controller = streamState.controller + const modelID = decodeMultibaseToStreamID(streamState.dimensions.model) + return { + commitID: CommitID.fromStream(streamID, streamState.event_cid), + content: decodedData.content as ModelDefinition | null, + metadata: { + model: modelID, + controller: controller as DIDString, + ...(typeof decodedData.metadata === 'object' + ? decodedData.metadata + : {}), + }, + } + } +} + +export type ModelState = { + commitID: CommitID + content: ModelDefinition | null + metadata: ModelMetadata +} +/** + * Parameters required to update a model stream. + */ +export type UpdateModelDefinitionParams = { + /** String representation of the StreamID to update */ + streamID: string + /** New JSON object content for the stream, used with `currentContent` to create a JSON patch */ + newContent: ModelDefinition + /** Current model definition if known containing the stream's current state */ + currentState?: StreamState + /** Optional `DID` instance for signing the model definition. **/ + controller?: DID +} + +/** + * Parameters for posting a data event to a model stream. + */ +export type PostDefinitionParams = Omit & { + controller?: DID +} + +/** + * Parameters required to create a signed data event for a Model stream. + */ +export type CreateDataEventParams = { + /** DID controlling the ModelInstanceDocument stream */ + controller: DID + /** Commit ID of the current tip of the ModelInstanceDocument stream */ + currentID: CommitID + /** Current JSON object content for the stream, used with `newContent` to create a JSON patch */ + currentContent?: ModelDefinition + /** New JSON object content for the stream, used with `currentContent` to create a JSON patch */ + newContent?: ModelDefinition } diff --git a/packages/model-instance-client/src/client.ts b/packages/model-instance-client/src/client.ts index 363df88..59d763f 100644 --- a/packages/model-instance-client/src/client.ts +++ b/packages/model-instance-client/src/client.ts @@ -156,10 +156,12 @@ export class ModelInstanceClient extends StreamClient { * @returns The `DocumentState` derived from the stream state. */ streamStateToDocumentState(streamState: StreamState): DocumentState { + const streamID = StreamID.fromString(streamState.id) const decodedData = decodeMultibaseToJSON(streamState.data) const controller = streamState.controller const modelID = decodeMultibaseToStreamID(streamState.dimensions.model) return { + commitID: CommitID.fromStream(streamID, streamState.event_cid), content: decodedData.content as UnknownContent | null, metadata: { model: modelID, @@ -216,17 +218,19 @@ export class ModelInstanceClient extends StreamClient { } const { content } = currentState - const { controller, newContent, shouldIndex } = params + const { controller, newContent, shouldIndex, modelVersion } = params - await this.postData({ + const newCommit = await this.postData({ controller: this.getDID(controller), currentContent: content ?? undefined, newContent, currentID: currentId, shouldIndex, + modelVersion, }) return { + commitID: newCommit, content: newContent, metadata: { model: currentState.metadata.model, diff --git a/packages/model-instance-client/src/events.ts b/packages/model-instance-client/src/events.ts index 8675695..7dd0ca3 100644 --- a/packages/model-instance-client/src/events.ts +++ b/packages/model-instance-client/src/events.ts @@ -14,6 +14,7 @@ import { } from '@ceramic-sdk/model-instance-protocol' import type { DIDString } from '@didtools/codecs' import type { DID } from 'dids' +import type { CID } from 'multiformats/cid' import type { StreamState } from '@ceramic-sdk/stream-client' import type { UnknownContent } from './types.js' @@ -29,6 +30,9 @@ export type CreateInitEventParams = { controller: DID /** Stream ID of the Model used by the ModelInstanceDocument stream */ model: StreamID + /** CID of specific model version to use when validating this instance. + * When empty the the init commit of the model is used */ + modelVersion?: CID /** Optional context */ context?: StreamID /** Flag indicating if indexers should index the ModelInstanceDocument stream (defaults to `true`) */ @@ -151,6 +155,9 @@ export type CreateDataEventParams = { newContent?: T /** Flag indicating if indexers should index the stream */ shouldIndex?: boolean + /** CID of specific model version to use when validating this instance. + * When empty the the init commit of the model is used */ + modelVersion?: CID } /** @@ -165,6 +172,9 @@ export type PostDataEventParams = { currentState?: StreamState /** Flag indicating if indexers should index the stream */ shouldIndex?: boolean + /** CID of specific model version to use when validating this instance. + * When empty the the init commit of the model is used */ + modelVersion?: CID } /** @@ -186,8 +196,13 @@ export async function createDataEvent< ) // Header must only be provided if there are values // CBOR encoding doesn't support undefined values - const header = - params.shouldIndex == null ? undefined : { shouldIndex: params.shouldIndex } + const header: DocumentDataEventHeader = {} + if (params.shouldIndex != null) { + header.shouldIndex = params.shouldIndex + } + if (params.modelVersion != null) { + header.modelVersion = params.modelVersion + } const payload = createDataEventPayload(params.currentID, operations, header) return await signEvent(params.controller, payload) } diff --git a/packages/model-instance-client/src/types.ts b/packages/model-instance-client/src/types.ts index 43145ec..a2e89c4 100644 --- a/packages/model-instance-client/src/types.ts +++ b/packages/model-instance-client/src/types.ts @@ -1,8 +1,10 @@ +import type { CommitID } from '@ceramic-sdk/identifiers' import type { DocumentMetadata } from '@ceramic-sdk/model-instance-protocol' export type UnknownContent = Record export type DocumentState = { + commitID: CommitID content: UnknownContent | null metadata: DocumentMetadata } diff --git a/packages/model-instance-client/src/utils.ts b/packages/model-instance-client/src/utils.ts index 41100a3..66e8233 100644 --- a/packages/model-instance-client/src/utils.ts +++ b/packages/model-instance-client/src/utils.ts @@ -5,6 +5,7 @@ import { } from '@ceramic-sdk/model-instance-protocol' import { type DIDString, asDIDString } from '@didtools/codecs' import jsonpatch from 'fast-json-patch' +import type { CID } from 'multiformats/cid' import type { UnknownContent } from './types.js' @@ -34,6 +35,9 @@ export function randomBytes(length: number): Uint8Array { export type CreateInitHeaderParams = { /** The stream ID of the model associated with the document. */ model: StreamID + /** CID of specific model version to use when validating this instance. + * When empty the the init commit of the model is used */ + modelVersion?: CID /** The DID string or literal string representing the controller of the document. */ controller: DIDString | string /** A unique value to ensure determinism, or a boolean to indicate uniqueness type. */ @@ -87,6 +91,9 @@ export function createInitHeader( if (params.shouldIndex != null) { header.shouldIndex = params.shouldIndex } + if (params.modelVersion != null) { + header.modelVersion = params.modelVersion + } // Validate header before returning if (!DocumentInitEventHeader.is(header)) { diff --git a/packages/model-instance-client/test/lib.test.ts b/packages/model-instance-client/test/lib.test.ts index aa83432..35814a3 100644 --- a/packages/model-instance-client/test/lib.test.ts +++ b/packages/model-instance-client/test/lib.test.ts @@ -126,7 +126,7 @@ describe('createDataEvent()', () => { { op: 'replace', path: '/hello', value: 'world' }, { op: 'add', path: '/test', value: true }, ]) - expect(payload.header).toBeUndefined() + expect(payload.header).toEqual({}) }) test('adds the shouldIndex header when provided', async () => { diff --git a/packages/model-instance-protocol/src/codecs.ts b/packages/model-instance-protocol/src/codecs.ts index 728b095..5d92692 100644 --- a/packages/model-instance-protocol/src/codecs.ts +++ b/packages/model-instance-protocol/src/codecs.ts @@ -102,6 +102,7 @@ export const DocumentInitEventHeader = sparse( { controllers: tuple([didString]), model: streamIDAsBytes, + modelVersion: optional(cid), sep: literal('model'), unique: optional(uint8array), context: optional(streamIDAsBytes), @@ -155,6 +156,7 @@ export type DocumentInitEventPayload = TypeOf export const DocumentDataEventHeader = sparse( { shouldIndex: optional(boolean), + modelVersion: optional(cid), }, 'DocumentDataEventHeader', ) diff --git a/packages/model-protocol/src/codecs.ts b/packages/model-protocol/src/codecs.ts index 34c6d45..47d80d2 100644 --- a/packages/model-protocol/src/codecs.ts +++ b/packages/model-protocol/src/codecs.ts @@ -4,7 +4,7 @@ import { streamIDAsString, streamIDString, } from '@ceramic-sdk/identifiers' -import { didString } from '@didtools/codecs' +import { cid, didString } from '@didtools/codecs' import addFormats from 'ajv-formats' import Ajv from 'ajv/dist/2020.js' import { @@ -23,8 +23,10 @@ import { string, tuple, union, + unknown, } from 'codeco' import type { JSONSchema } from 'json-schema-typed/draft-2020-12' +import 'multiformats' // Import needed for TS reference import 'ts-essentials' // Import needed for TS reference import { MODEL } from './constants.js' @@ -395,3 +397,86 @@ export type ModelInitEventPayload = TypeOf */ export const ModelEvent = union([SignedEvent, TimeEvent], 'ModelEvent') export type ModelEvent = TypeOf + +/** + * JSON patch operations. + */ + +export const JSONPatchAddOperation = strict( + { + op: literal('add'), + path: string, + value: unknown, + }, + 'JSONPatchAddOperation', +) + +export const JSONPatchRemoveOperation = strict( + { + op: literal('remove'), + path: string, + }, + 'JSONPatchRemoveOperation', +) + +export const JSONPatchReplaceOperation = strict( + { + op: literal('replace'), + path: string, + value: unknown, + }, + 'JSONPatchReplaceOperation', +) + +export const JSONPatchMoveOperation = strict( + { + op: literal('move'), + path: string, + from: string, + }, + 'JSONPatchMoveOperation', +) + +export const JSONPatchCopyOperation = strict( + { + op: literal('copy'), + path: string, + from: string, + }, + 'JSONPatchCopyOperation', +) + +export const JSONPatchTestOperation = strict( + { + op: literal('test'), + path: string, + value: unknown, + }, + 'JSONPatchTestOperation', +) + +export const JSONPatchOperation = union( + [ + JSONPatchAddOperation, + JSONPatchRemoveOperation, + JSONPatchReplaceOperation, + JSONPatchMoveOperation, + JSONPatchCopyOperation, + JSONPatchTestOperation, + ], + 'JSONPatchOperation', +) +export type JSONPatchOperation = TypeOf + +/** + * Data event payload for a Model stream + */ +export const ModelDataEventPayload = sparse( + { + data: array(JSONPatchOperation), + prev: cid, + id: cid, + }, + 'ModelDataEventPayload', +) +export type ModelDataEventPayload = TypeOf diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ddcc4fc..7a4eed4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -267,6 +267,12 @@ importers: '@ceramic-sdk/stream-client': specifier: workspace:^ version: link:../stream-client + '@didtools/codecs': + specifier: ^3.0.0 + version: 3.0.0 + fast-json-patch: + specifier: ^3.1.1 + version: 3.1.1 devDependencies: '@ceramic-sdk/http-client': specifier: workspace:^ @@ -372,6 +378,9 @@ importers: json-ptr: specifier: ^3.1.1 version: 3.1.1 + multiformats: + specifier: ^13.3.0 + version: 13.3.0 ts-essentials: specifier: ^10.0.2 version: 10.0.2(typescript@5.6.2) @@ -382,9 +391,6 @@ importers: json-schema-typed: specifier: ^8.0.1 version: 8.0.1 - multiformats: - specifier: ^13.3.0 - version: 13.3.0 packages/stream-client: dependencies: diff --git a/tests/c1-integration/test/model.test.ts b/tests/c1-integration/test/model.test.ts index 6f92863..0932fb6 100644 --- a/tests/c1-integration/test/model.test.ts +++ b/tests/c1-integration/test/model.test.ts @@ -5,6 +5,7 @@ import { } from '@ceramic-sdk/flight-sql-client' import { CeramicClient } from '@ceramic-sdk/http-client' import { ModelClient } from '@ceramic-sdk/model-client' +import { ModelInstanceClient } from '@ceramic-sdk/model-instance-client' import type { ModelDefinition } from '@ceramic-sdk/model-protocol' import { getAuthenticatedDID } from '@didtools/key-did' import CeramicOneContainer, { @@ -14,24 +15,8 @@ import CeramicOneContainer, { const authenticatedDID = await getAuthenticatedDID(new Uint8Array(32)) -const testModel: ModelDefinition = { - version: '2.0', - name: 'ListTestModel', - description: 'List Test model', - accountRelation: { type: 'list' }, - interface: false, - implements: [], - schema: { - type: 'object', - properties: { - test: { type: 'string', maxLength: 10 }, - }, - additionalProperties: false, - }, -} - const CONTAINER_OPTS: EnvironmentOptions = { - containerName: 'ceramic-test-model-MID-list', + containerName: 'ceramic-test-model', apiPort: 5222, flightSqlPort: 5223, testPort: 5223, @@ -56,7 +41,7 @@ const modelClient = new ModelClient({ did: authenticatedDID, }) -describe('model integration test for list model and MID', () => { +describe('model stream integration test', () => { let c1Container: CeramicOneContainer let flightClient: FlightSqlClient @@ -66,6 +51,22 @@ describe('model integration test for list model and MID', () => { }, 10000) test('create model', async () => { + const testModel: ModelDefinition = { + version: '2.0', + name: 'TestModelCreation', + description: 'List Test model', + accountRelation: { type: 'list' }, + interface: false, + implements: [], + schema: { + type: 'object', + properties: { + test: { type: 'string', maxLength: 10 }, + }, + additionalProperties: false, + }, + } + const modelStream = await modelClient.createDefinition(testModel) // Use the flightsql stream behavior to ensure the events states have been process before querying their states. await waitForEventState(flightClient, modelStream.cid) @@ -73,6 +74,191 @@ describe('model integration test for list model and MID', () => { const definition = await modelClient.getModelDefinition(modelStream) expect(definition).toEqual(testModel) }) + test('update model', async () => { + const testModel: ModelDefinition = { + version: '2.0', + name: 'TestModelUpdate', + description: 'List Test model', + accountRelation: { type: 'list' }, + interface: false, + implements: [], + schema: { + type: 'object', + properties: { + test: { type: 'string', maxLength: 10 }, + }, + additionalProperties: false, + }, + } + const testModelUpdated: ModelDefinition = { + version: '2.0', + name: 'UpdatedTestModel', + description: 'List Test model', + accountRelation: { type: 'list' }, + interface: false, + implements: [], + schema: { + type: 'object', + properties: { + test: { type: 'string', maxLength: 10 }, + new: { type: 'number' }, + }, + additionalProperties: false, + }, + } + const modelStream = await modelClient.createDefinition(testModel) + + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, modelStream.cid) + + const modelState = await modelClient.updateDefinition({ + streamID: modelStream.toString(), + newContent: testModelUpdated, + }) + + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, modelState.commitID.commit) + + const definition = await modelClient.getModelDefinition(modelStream) + expect(definition).toEqual(testModelUpdated) + }) + test('create instance for specific model version', async () => { + const testModel: ModelDefinition = { + version: '2.0', + name: 'TestModelInstanceCreate', + description: 'List Test model', + accountRelation: { type: 'list' }, + interface: false, + implements: [], + schema: { + type: 'object', + properties: { + test: { type: 'string', maxLength: 10 }, + }, + additionalProperties: false, + }, + } + const testModelUpdated: ModelDefinition = { + version: '2.0', + name: 'UpdatedTestModelInstanceCreate', + description: 'List Test model', + accountRelation: { type: 'list' }, + interface: false, + implements: [], + schema: { + type: 'object', + properties: { + test: { type: 'string', maxLength: 10 }, + new: { type: 'number' }, + }, + additionalProperties: false, + }, + } + const modelInstanceClient = new ModelInstanceClient({ + ceramic: client, + did: authenticatedDID, + }) + const modelStream = await modelClient.createDefinition(testModel) + + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, modelStream.cid) + + const modelState = await modelClient.updateDefinition({ + streamID: modelStream.toString(), + newContent: testModelUpdated, + }) + + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, modelState.commitID.commit) + + // Create model instance that references the updated model version + const documentStream = await modelInstanceClient.createInstance({ + model: modelStream, + modelVersion: modelState.commitID.commit, + content: { test: 'hello', new: 42 }, + shouldIndex: true, + }) + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, documentStream.commit) + + const currentState = await modelInstanceClient.getDocumentState( + documentStream.baseID, + ) + expect(currentState.content).toEqual({ test: 'hello', new: 42 }) + }) + test('update instance for specific model version', async () => { + const testModel: ModelDefinition = { + version: '2.0', + name: 'TestModelInstanceUpdate', + description: 'List Test model', + accountRelation: { type: 'list' }, + interface: false, + implements: [], + schema: { + type: 'object', + properties: { + test: { type: 'string', maxLength: 10 }, + }, + additionalProperties: false, + }, + } + const testModelUpdated: ModelDefinition = { + version: '2.0', + name: 'UpdatedTestModelInstanceUpdate', + description: 'List Test model', + accountRelation: { type: 'list' }, + interface: false, + implements: [], + schema: { + type: 'object', + properties: { + test: { type: 'string', maxLength: 10 }, + new: { type: 'number' }, + }, + additionalProperties: false, + }, + } + const modelInstanceClient = new ModelInstanceClient({ + ceramic: client, + did: authenticatedDID, + }) + const modelStream = await modelClient.createDefinition(testModel) + + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, modelStream.cid) + + const modelState = await modelClient.updateDefinition({ + streamID: modelStream.toString(), + newContent: testModelUpdated, + }) + + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, modelState.commitID.commit) + + // Create model instance that references the updated model version + const documentStream = await modelInstanceClient.createInstance({ + model: modelStream, + content: { test: 'hello' }, + shouldIndex: true, + }) + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, documentStream.commit) + + // update the document + const updatedState = await modelInstanceClient.updateDocument({ + streamID: documentStream.baseID.toString(), + modelVersion: modelState.commitID.commit, + newContent: { test: 'world', new: 42 }, + shouldIndex: true, + }) + // Use the flightsql stream behavior to ensure the events states have been process before querying their states. + await waitForEventState(flightClient, updatedState.commitID.commit) + + const currentState = await modelInstanceClient.getDocumentState( + documentStream.baseID, + ) + expect(currentState.content).toEqual({ test: 'world', new: 42 }) + }) afterAll(async () => { await c1Container.teardown() }) From e1f08e1ee23286f43b9f4d8fe0612d8734433248 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Wed, 26 Feb 2025 08:45:17 -0700 Subject: [PATCH 2/5] chore: update lock file --- pnpm-lock.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a4eed4..d9f43ce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -378,9 +378,6 @@ importers: json-ptr: specifier: ^3.1.1 version: 3.1.1 - multiformats: - specifier: ^13.3.0 - version: 13.3.0 ts-essentials: specifier: ^10.0.2 version: 10.0.2(typescript@5.6.2) @@ -391,6 +388,9 @@ importers: json-schema-typed: specifier: ^8.0.1 version: 8.0.1 + multiformats: + specifier: ^13.3.0 + version: 13.3.0 packages/stream-client: dependencies: From f69e6b155210f24ad9c581aa1895dc3a6947da07 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Wed, 26 Feb 2025 09:32:03 -0700 Subject: [PATCH 3/5] chore: use cargo.lock as we are effectively a binary crate --- .gitignore | 3 +- packages/flight-sql-client/Cargo.lock | 2047 +++++++++++++++++++++++++ 2 files changed, 2048 insertions(+), 2 deletions(-) create mode 100644 packages/flight-sql-client/Cargo.lock diff --git a/.gitignore b/.gitignore index c4ed4d5..4f7c48e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,5 @@ coverage # rust target -Cargo.lock # napi binaries -*.node \ No newline at end of file +*.node diff --git a/packages/flight-sql-client/Cargo.lock b/packages/flight-sql-client/Cargo.lock new file mode 100644 index 0000000..4d8b2f1 --- /dev/null +++ b/packages/flight-sql-client/Cargo.lock @@ -0,0 +1,2047 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "const-random", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "arrow-arith" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "855c57c4efd26722b044dcd3e348252560e3e0333087fb9f6479dc0bf744054f" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "num", +] + +[[package]] +name = "arrow-array" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd03279cea46569acf9295f6224fbc370c5df184b4d2ecfe97ccb131d5615a7f" +dependencies = [ + "ahash", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "hashbrown 0.15.1", + "num", +] + +[[package]] +name = "arrow-buffer" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e4a9b9b1d6d7117f6138e13bc4dd5daa7f94e671b70e8c9c4dc37b4f5ecfc16" +dependencies = [ + "bytes", + "half", + "num", +] + +[[package]] +name = "arrow-cast" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc70e39916e60c5b7af7a8e2719e3ae589326039e1e863675a008bee5ffe90fd" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "atoi", + "base64", + "chrono", + "half", + "lexical-core", + "num", + "ryu", +] + +[[package]] +name = "arrow-data" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e75edf21ffd53744a9b8e3ed11101f610e7ceb1a29860432824f1834a1f623" +dependencies = [ + "arrow-buffer", + "arrow-schema", + "half", + "num", +] + +[[package]] +name = "arrow-flight" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c09b331887a526f203f2123444792aee924632bd08b9940435070901075832e" +dependencies = [ + "arrow-arith", + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-ipc", + "arrow-ord", + "arrow-row", + "arrow-schema", + "arrow-select", + "arrow-string", + "base64", + "bytes", + "futures", + "once_cell", + "paste", + "prost", + "prost-types", + "tokio", + "tonic", +] + +[[package]] +name = "arrow-ipc" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d186a909dece9160bf8312f5124d797884f608ef5435a36d9d608e0b2a9bcbf8" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast", + "arrow-data", + "arrow-schema", + "flatbuffers", +] + +[[package]] +name = "arrow-ord" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece7b5bc1180e6d82d1a60e1688c199829e8842e38497563c3ab6ea813e527fd" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "half", + "num", +] + +[[package]] +name = "arrow-row" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "745c114c8f0e8ce211c83389270de6fbe96a9088a7b32c2a041258a443fe83ff" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "half", +] + +[[package]] +name = "arrow-schema" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95513080e728e4cec37f1ff5af4f12c9688d47795d17cda80b6ec2cf74d4678" + +[[package]] +name = "arrow-select" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e415279094ea70323c032c6e739c48ad8d80e78a09bef7117b8718ad5bf3722" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "num", +] + +[[package]] +name = "arrow-string" +version = "53.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d956cae7002eb8d83a27dbd34daaea1cf5b75852f0b84deb4d93a276e92bbf" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select", + "memchr", + "num", + "regex", + "regex-syntax 0.8.5", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 1.0.2", + "tower 0.5.1", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets", +] + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "ctor" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "data-encoding" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f" + +[[package]] +name = "data-encoding-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b16d9d0d88a5273d830dac8b78ceb217ffc9b1d5404e5597a3542515329405b" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145d32e826a7748b69ee8fc62d3e6355ff7f1051df53141e7048162fc90481b" +dependencies = [ + "data-encoding", + "syn", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "flatbuffers" +version = "24.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8add37afff2d4ffa83bc748a70b4b1370984f6980768554182424ef71447c35f" +dependencies = [ + "bitflags 1.3.2", + "rustc_version", +] + +[[package]] +name = "flight-sql-client" +version = "0.1.0" +dependencies = [ + "arrow-array", + "arrow-cast", + "arrow-flight", + "arrow-ipc", + "arrow-schema", + "async-stream", + "futures", + "multibase", + "napi", + "napi-build", + "napi-derive", + "snafu", + "tokio", + "tonic", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", + "num-traits", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.1", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lexical-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0431c65b318a590c1de6b8fd6e72798c92291d27762d94c9e6c37ed7a73d8458" +dependencies = [ + "lexical-parse-float", + "lexical-parse-integer", + "lexical-util", + "lexical-write-float", + "lexical-write-integer", +] + +[[package]] +name = "lexical-parse-float" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb17a4bdb9b418051aa59d41d65b1c9be5affab314a872e5ad7f06231fb3b4e0" +dependencies = [ + "lexical-parse-integer", + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-parse-integer" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5df98f4a4ab53bf8b175b363a34c7af608fe31f93cc1fb1bf07130622ca4ef61" +dependencies = [ + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-util" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85314db53332e5c192b6bca611fb10c114a80d1b831ddac0af1e9be1b9232ca0" +dependencies = [ + "static_assertions", +] + +[[package]] +name = "lexical-write-float" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e7c3ad4e37db81c1cbe7cf34610340adc09c322871972f74877a712abc6c809" +dependencies = [ + "lexical-util", + "lexical-write-integer", + "static_assertions", +] + +[[package]] +name = "lexical-write-integer" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb89e9f6958b83258afa3deed90b5de9ef68eef090ad5086c791cd2345610162" +dependencies = [ + "lexical-util", + "static_assertions", +] + +[[package]] +name = "libc" +version = "0.2.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "napi" +version = "2.16.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214f07a80874bb96a8433b3cdfc84980d56c7b02e1a0d7ba4ba0db5cef785e2b" +dependencies = [ + "bitflags 2.6.0", + "ctor", + "napi-derive", + "napi-sys", + "once_cell", + "tokio", +] + +[[package]] +name = "napi-build" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1c0f5d67ee408a4685b61f5ab7e58605c8ae3f2b4189f0127d804ff13d5560a" + +[[package]] +name = "napi-derive" +version = "2.16.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17435f7a00bfdab20b0c27d9c56f58f6499e418252253081bfff448099da31d1" +dependencies = [ + "cfg-if", + "convert_case", + "napi-derive-backend", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "napi-derive-backend" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "967c485e00f0bf3b1bdbe510a38a4606919cf1d34d9a37ad41f25a81aa077abe" +dependencies = [ + "convert_case", + "once_cell", + "proc-macro2", + "quote", + "regex", + "semver", + "syn", +] + +[[package]] +name = "napi-sys" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3" +dependencies = [ + "libloading", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.23.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "snafu" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +dependencies = [ + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tokio" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost", + "rustls-pemfile", + "socket2", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" From 9ca01824bee18100e5677a5e05be1e975182fec6 Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Wed, 26 Feb 2025 09:51:08 -0700 Subject: [PATCH 4/5] chore: more deps fixes --- packages/model-instance-client/package.json | 3 ++- pnpm-lock.yaml | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/model-instance-client/package.json b/packages/model-instance-client/package.json index 4a52949..c805b45 100644 --- a/packages/model-instance-client/package.json +++ b/packages/model-instance-client/package.json @@ -35,7 +35,8 @@ "@ceramic-sdk/model-instance-protocol": "workspace:^", "@ceramic-sdk/stream-client": "workspace:^", "@didtools/codecs": "^3.0.0", - "fast-json-patch": "^3.1.1" + "fast-json-patch": "^3.1.1", + "multiformats": "^13.3.0" }, "devDependencies": { "@ceramic-sdk/http-client": "workspace:^", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d9f43ce..1d5fbb9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -310,6 +310,9 @@ importers: fast-json-patch: specifier: ^3.1.1 version: 3.1.1 + multiformats: + specifier: ^13.3.0 + version: 13.3.0 devDependencies: '@ceramic-sdk/http-client': specifier: workspace:^ From c0a2a46d080f4ffc8a147f2d892d2631b9e17c8c Mon Sep 17 00:00:00 2001 From: Nathaniel Cook Date: Wed, 26 Feb 2025 14:49:41 -0700 Subject: [PATCH 5/5] fix: ensure empty header is undefined --- packages/model-instance-client/src/events.ts | 5 ++++- packages/model-instance-client/test/lib.test.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/model-instance-client/src/events.ts b/packages/model-instance-client/src/events.ts index 7dd0ca3..4d9dd37 100644 --- a/packages/model-instance-client/src/events.ts +++ b/packages/model-instance-client/src/events.ts @@ -196,13 +196,16 @@ export async function createDataEvent< ) // Header must only be provided if there are values // CBOR encoding doesn't support undefined values - const header: DocumentDataEventHeader = {} + let header: DocumentDataEventHeader | undefined = {} if (params.shouldIndex != null) { header.shouldIndex = params.shouldIndex } if (params.modelVersion != null) { header.modelVersion = params.modelVersion } + if (Object.keys(header).length === 0) { + header = undefined + } const payload = createDataEventPayload(params.currentID, operations, header) return await signEvent(params.controller, payload) } diff --git a/packages/model-instance-client/test/lib.test.ts b/packages/model-instance-client/test/lib.test.ts index 35814a3..aa83432 100644 --- a/packages/model-instance-client/test/lib.test.ts +++ b/packages/model-instance-client/test/lib.test.ts @@ -126,7 +126,7 @@ describe('createDataEvent()', () => { { op: 'replace', path: '/hello', value: 'world' }, { op: 'add', path: '/test', value: true }, ]) - expect(payload.header).toEqual({}) + expect(payload.header).toBeUndefined() }) test('adds the shouldIndex header when provided', async () => {