diff --git a/examples/prebuilt-react-integration/src/main.css b/examples/prebuilt-react-integration/src/main.css index f736378b9a..83b726cacd 100644 --- a/examples/prebuilt-react-integration/src/main.css +++ b/examples/prebuilt-react-integration/src/main.css @@ -1,3 +1,5 @@ +@import url('@100mslive/roomkit-react/index.css'); + html, body, #root { @@ -17,3 +19,7 @@ body { width: 100%; margin: 0; } + +.tl-container { + border-radius: 0.75rem; +} diff --git a/packages/hms-whiteboard/.eslintrc b/packages/hms-whiteboard/.eslintrc new file mode 100644 index 0000000000..3bac8a72fa --- /dev/null +++ b/packages/hms-whiteboard/.eslintrc @@ -0,0 +1,87 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/recommended", + "plugin:import/typescript", + "react-app", + "react-app/jest" + ], + "plugins": ["prettier", "simple-import-sort"], + "rules": { + "@typescript-eslint/ban-ts-comment": 0, + "@typescript-eslint/no-unused-vars": "error", + "no-nested-ternary": 1, + "no-unused-vars": [ + "error", + { + "vars": "all", + "args": "none", + "ignoreRestSiblings": false + } + ], + "react/react-in-jsx-scope": "error", + "react/jsx-curly-brace-presence": [ + 2, + { + "props": "never" + } + ], + "react/self-closing-comp": [ + "error", + { + "component": true, + "html": false + } + ], + "prettier/prettier": [ + "error", + { + "endOfLine": "auto" // This is need to handle different end-of-line in windows/mac + } + ], + "import/first": "error", + "import/namespace": [2, { "allowComputed": true }], + "import/no-duplicates": "error", + "simple-import-sort/imports": [ + "error", + { + "groups": [ + [ + // Packages `react` related packages come first. + "^react", + "^@?\\w", + // Internal packages. + "^@100mslive/react-sdk", + "^@100mslive/react-icons", + // Side effect imports. + "^\\u0000", + + "(components)", + // Other relative imports. Put same-folder imports and `.`. + "^\\./(?=.*/)(?!/?$)", + "^\\.(?!/?$)", + "^\\./?$", + "(plugins)", + "(components)?(.*)(/use.*)", + ".*(hooks)", + "(common)", + "(services)", + "(utils)", + "(constants)", + // Style imports. + "^.+\\.?(css)$" + ] + ] + } + ] + }, + "settings": { + "import/resolver": { + "node": { + "extensions": [".js", ".jsx", ".ts", ".tsx"] + } + } + }, + "ignorePatterns": ["src/*.css", "src/images/*", "src/grpc/*", "dist/**"] +} diff --git a/packages/hms-whiteboard/package.json b/packages/hms-whiteboard/package.json new file mode 100644 index 0000000000..fb67876922 --- /dev/null +++ b/packages/hms-whiteboard/package.json @@ -0,0 +1,61 @@ +{ + "name": "@100mslive/hms-whiteboard", + "author": "100ms", + "license": "MIT", + "version": "0.0.0-alpha.2", + "main": "dist/index.cjs.js", + "module": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "exports": { + ".": { + "require": "./dist/index.cjs.js", + "import": "./dist/index.js", + "default": "./dist/index.js" + }, + "./index.css": "./dist/index.css" + }, + "sideEffects": false, + "scripts": { + "prestart": "rm -rf dist", + "start": "rollup -c -w", + "build": "rm -rf dist && NODE_ENV=production rollup -c", + "build:proto": "protoc --ts_opt long_type_string --ts_out ./src/grpc -I=./proto proto/*proto", + "lint": "eslint -c .eslintrc src", + "lint:fix": "eslint -c .eslintrc src --fix", + "format": "prettier -w src/**" + }, + "dependencies": { + "@protobuf-ts/grpcweb-transport": "^2.9.1", + "@protobuf-ts/runtime": "^2.9.1", + "@protobuf-ts/runtime-rpc": "^2.9.1", + "@tldraw/tldraw": "2.0.0-alpha.19" + }, + "peerDependencies": { + "react": ">=17.0.2 <19.0.0", + "react-dom": ">=17.0.2 <19.0.0" + }, + "devDependencies": { + "@protobuf-ts/plugin": "^2.9.1", + "@types/node": "^20.12.5", + "@types/react": "^18.1.0", + "@types/react-dom": "^18.1.0", + "eslint": "^8.53.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.4", + "grpc-tools": "^1.12.4", + "react": "^18.1.0", + "react-dom": "^18.1.0", + "typescript": "^5.2.2", + "@rollup/plugin-commonjs": "^21.0.3", + "@rollup/plugin-node-resolve": "^13.1.3", + "@rollup/plugin-replace": "^5.0.1", + "@rollup/plugin-typescript": "^8.3.1", + "rollup": "^2.70.1", + "rollup-plugin-esbuild": "^4.9.3", + "rollup-plugin-import-css": "^3.5.0", + "rollup-plugin-terser": "^7.0.2" + } +} diff --git a/packages/hms-whiteboard/proto/sessionstore.proto b/packages/hms-whiteboard/proto/sessionstore.proto new file mode 100644 index 0000000000..fc7190cbe8 --- /dev/null +++ b/packages/hms-whiteboard/proto/sessionstore.proto @@ -0,0 +1,129 @@ +syntax = "proto3"; + +package sessionstorepb; + +option go_package = "./internal;sessionstorepb"; + +import "google/protobuf/timestamp.proto"; + +service Api { + rpc Hello(HelloRequest) returns (HelloResponse) {} + rpc Subscribe(SubscribeRequest) returns (stream Event) {} +} + +message HelloRequest { + string name = 1; +} + +message HelloResponse { + string response = 1; +} + +message SubscribeRequest { + string name = 1; + int64 offset = 2; +} + +message Event { + string message = 1; + int64 sequence = 2; +} + +// metadata token -> session id, room id, user id, username + +// open is used for presence + +// change stream will return all keys in order of oldest to newsest. + +// max number of keys -> 5000 +// max size per key -> 10240 Bytes + +service Store { + // open - start listening to updates in keys with provided match patterns + // provide change_id as last received ID to resume updates + rpc open(OpenRequest) returns (stream ChangeStream) {} + + // get last stored value in given key + rpc get(GetRequest) returns (GetResponse) {} + + // set key value + rpc set(SetRequest) returns (SetResponse) {} + + // delete key from store + rpc delete (DeleteRequest) returns (DeleteResponse) {} + + // count get count of keys + rpc count(CountRequest) returns (CountResponse) {} +} + +// define new structure for value based on client needs and add support in +// following message +message Value { + enum Type { + NONE = 0; + BYTES = 1; + STRING = 2; + INTEGER = 3; + FLOAT = 4; + } + Type type = 1; + oneof Data { + int64 number = 2; + float float = 3; + string str = 4; + bytes raw_bytes = 5; + } +} + +message GetRequest { + string key = 1; +} + +message GetResponse { + string key = 1; + string namespace = 2; + Value value = 3; +} + +message DeleteRequest { + string key = 1; +} + +message DeleteResponse {} + +message SetRequest { + string key = 1; + Value value = 3; +} + +message SetResponse {} + +message ChangeStream { + string change_id = 1; + string key = 2; + string namespace = 3; + Value value = 4; + string from_id = 5; +} + +message Select { + oneof match { + string all = 1; // match all keys + string key = 2; // match key + string prefix = 3; // match keys with given prefix + string suffix = 4; // match keys with given suffix + } +} + +message OpenRequest { + // last received change_id for reconnection, "" if first connection + string change_id = 1; + repeated Select select = 3; +} + +message CountRequest {} + +message CountResponse { + int64 count = 1; +} + diff --git a/packages/hms-whiteboard/rollup.config.js b/packages/hms-whiteboard/rollup.config.js new file mode 100644 index 0000000000..80f752c7c1 --- /dev/null +++ b/packages/hms-whiteboard/rollup.config.js @@ -0,0 +1,31 @@ +import resolve from '@rollup/plugin-node-resolve'; +import typescript from '@rollup/plugin-typescript'; +import esbuild from 'rollup-plugin-esbuild'; +import { terser } from 'rollup-plugin-terser'; +import pkg from './package.json'; +import commonjs from '@rollup/plugin-commonjs'; +import css from 'rollup-plugin-import-css'; + +const isProduction = process.env.NODE_ENV === 'production'; + +const deps = Object.keys(pkg.dependencies || {}); +const peerDeps = Object.keys(pkg.peerDependencies || {}); + +const config = { + input: 'src/index.ts', + external: [...deps, ...peerDeps], + output: [ + { file: pkg.main, format: 'cjs', sourcemap: true }, + { dir: 'dist', format: 'esm', preserveModules: true, preserveModulesRoot: 'src', sourcemap: true }, + ], + plugins: [ + commonjs(), + css({ output: 'index.css' }), + esbuild({ format: 'esm' }), + resolve(), + isProduction && terser(), + typescript({ sourceMap: true }), + ], +}; + +export default config; diff --git a/packages/hms-whiteboard/src/ErrorFallback.tsx b/packages/hms-whiteboard/src/ErrorFallback.tsx new file mode 100644 index 0000000000..871a924079 --- /dev/null +++ b/packages/hms-whiteboard/src/ErrorFallback.tsx @@ -0,0 +1,168 @@ +import React, { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'; +import { useValue } from '@tldraw/state'; +import { Editor, hardResetEditor, refreshPage } from '@tldraw/tldraw'; +import classNames from 'classnames'; + +const DISCORD_URL = 'https://discord.gg/pTge2BwDBq'; + +export type TLErrorFallbackComponent = ComponentType<{ + error: unknown; + editor?: Editor; +}>; + +export const ErrorFallback: TLErrorFallbackComponent = ({ error, editor }) => { + const containerRef = useRef(null); + const [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV !== 'production'); + const [didCopy, setDidCopy] = useState(false); + const [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false); + + const errorMessage = error instanceof Error ? error.message : String(error); + const errorStack = error instanceof Error ? error.stack : null; + + const isDarkModeFromApp = useValue( + 'isDarkMode', + () => { + try { + if (editor) { + return editor.user.isDarkMode; + } + } catch { + // we're in a funky error state so this might not work for spooky + // reasons. if not, we'll have another attempt later: + } + return null; + }, + [editor], + ); + const [isDarkMode, setIsDarkMode] = useState(null); + useLayoutEffect(() => { + // if we found a theme class from the app, we can just use that + if (isDarkModeFromApp !== null) { + setIsDarkMode(isDarkModeFromApp); + } + + // do any of our parents have a theme class? if yes then we can just + // rely on that and don't need to set our own class + let parent = containerRef.current?.parentElement; + let foundParentThemeClass = false; + while (parent) { + if (parent.classList.contains('tl-theme__dark') || parent.classList.contains('tl-theme__light')) { + foundParentThemeClass = true; + break; + } + parent = parent.parentElement; + } + if (foundParentThemeClass) { + setIsDarkMode(null); + return; + } + + // if we can't find a theme class from the app or from a parent, we have + // to fall back on using a media query: + setIsDarkMode(window.matchMedia('(prefers-color-scheme: dark)').matches); + }, [isDarkModeFromApp]); + + useEffect(() => { + if (didCopy) { + const timeout = setTimeout(() => { + setDidCopy(false); + }, 2000); + return () => clearTimeout(timeout); + } + }, [didCopy]); + + const copyError = () => { + const textarea = document.createElement('textarea'); + textarea.value = errorStack ?? errorMessage; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand('copy'); + textarea.remove(); + setDidCopy(true); + }; + + const refresh = () => { + refreshPage(); + }; + + const resetLocalState = async () => { + hardResetEditor(); + }; + + return ( +
+
+ {/* {editor && ( + // opportunistically attempt to render the canvas to reassure + // the user that their document is still there. there's a good + // chance this won't work (ie the error that we're currently + // notifying the user about originates in the canvas) so it's + // not a big deal if it doesn't work - in that case we just have + // a plain grey background. + null}> + +
+ +
+
+
+ )} */} +
+ {shouldShowResetConfirmation ? ( + <> +

Are you sure?

+

Resetting your data will delete your drawing and cannot be undone.

+
+ + +
+ + ) : ( + <> +

Something's gone wrong.

+

+ Sorry, we encountered an error. Please refresh the page to continue. If you keep seeing this error, you + can ask for help on Discord. +

+ {shouldShowError && ( +
+
+                  {errorStack ?? errorMessage}
+                
+ +
+ )} +
+ +
+ + +
+
+ + )} +
+
+ ); +}; diff --git a/packages/hms-whiteboard/src/Whiteboard.tsx b/packages/hms-whiteboard/src/Whiteboard.tsx new file mode 100644 index 0000000000..02439ab493 --- /dev/null +++ b/packages/hms-whiteboard/src/Whiteboard.tsx @@ -0,0 +1,40 @@ +import React, { useState } from 'react'; +import { Editor, Tldraw } from '@tldraw/tldraw'; +import { ErrorFallback } from './ErrorFallback'; +import { useCollaboration } from './hooks/useCollaboration'; +import './index.css'; + +export interface WhiteboardProps { + endpoint?: string; + token?: string; + zoomToContent?: boolean; + transparentCanvas?: boolean; + onMount?: (args: { store?: unknown; editor?: unknown }) => void; +} +export function Whiteboard({ onMount, endpoint, token, zoomToContent, transparentCanvas }: WhiteboardProps) { + const [editor, setEditor] = useState(); + const store = useCollaboration({ + endpoint, + token, + editor, + zoomToContent, + }); + + const handleMount = (editor: Editor) => { + setEditor(editor); + // @ts-expect-error - for debugging + window.editor = editor; + onMount?.({ store: store.store, editor }); + }; + + return ( + + ); +} diff --git a/packages/hms-whiteboard/src/grpc/sessionstore.client.ts b/packages/hms-whiteboard/src/grpc/sessionstore.client.ts new file mode 100644 index 0000000000..d5a584987b --- /dev/null +++ b/packages/hms-whiteboard/src/grpc/sessionstore.client.ts @@ -0,0 +1,174 @@ +// @generated by protobuf-ts 2.9.4 with parameter long_type_string +// @generated from protobuf file "sessionstore.proto" (package "sessionstorepb", syntax proto3) +// tslint:disable +import type { RpcOptions, RpcTransport, ServerStreamingCall, ServiceInfo, UnaryCall } from '@protobuf-ts/runtime-rpc'; +import { stackIntercept } from '@protobuf-ts/runtime-rpc'; +import type { + ChangeStream, + CountRequest, + CountResponse, + DeleteRequest, + DeleteResponse, + Event, + GetRequest, + GetResponse, + HelloRequest, + HelloResponse, + OpenRequest, + SetRequest, + SetResponse, + SubscribeRequest, +} from './sessionstore'; +import { Api, Store } from './sessionstore'; +/** + * @generated from protobuf service sessionstorepb.Api + */ +export interface IApiClient { + /** + * @generated from protobuf rpc: Hello(sessionstorepb.HelloRequest) returns (sessionstorepb.HelloResponse); + */ + hello(input: HelloRequest, options?: RpcOptions): UnaryCall; + /** + * @generated from protobuf rpc: Subscribe(sessionstorepb.SubscribeRequest) returns (stream sessionstorepb.Event); + */ + subscribe(input: SubscribeRequest, options?: RpcOptions): ServerStreamingCall; +} +/** + * @generated from protobuf service sessionstorepb.Api + */ +export class ApiClient implements IApiClient, ServiceInfo { + typeName = Api.typeName; + methods = Api.methods; + options = Api.options; + constructor(private readonly _transport: RpcTransport) {} + /** + * @generated from protobuf rpc: Hello(sessionstorepb.HelloRequest) returns (sessionstorepb.HelloResponse); + */ + hello(input: HelloRequest, options?: RpcOptions): UnaryCall { + const method = this.methods[0], + opt = this._transport.mergeOptions(options); + return stackIntercept('unary', this._transport, method, opt, input); + } + /** + * @generated from protobuf rpc: Subscribe(sessionstorepb.SubscribeRequest) returns (stream sessionstorepb.Event); + */ + subscribe(input: SubscribeRequest, options?: RpcOptions): ServerStreamingCall { + const method = this.methods[1], + opt = this._transport.mergeOptions(options); + return stackIntercept('serverStreaming', this._transport, method, opt, input); + } +} +// metadata token -> session id, room id, user id, username + +// open is used for presence + +// change stream will return all keys in order of oldest to newsest. + +// max number of keys -> 5000 +// max size per key -> 10240 Bytes + +/** + * @generated from protobuf service sessionstorepb.Store + */ +export interface IStoreClient { + /** + * open - start listening to updates in keys with provided match patterns + * provide change_id as last received ID to resume updates + * + * @generated from protobuf rpc: open(sessionstorepb.OpenRequest) returns (stream sessionstorepb.ChangeStream); + */ + open(input: OpenRequest, options?: RpcOptions): ServerStreamingCall; + /** + * get last stored value in given key + * + * @generated from protobuf rpc: get(sessionstorepb.GetRequest) returns (sessionstorepb.GetResponse); + */ + get(input: GetRequest, options?: RpcOptions): UnaryCall; + /** + * set key value + * + * @generated from protobuf rpc: set(sessionstorepb.SetRequest) returns (sessionstorepb.SetResponse); + */ + set(input: SetRequest, options?: RpcOptions): UnaryCall; + /** + * delete key from store + * + * @generated from protobuf rpc: delete(sessionstorepb.DeleteRequest) returns (sessionstorepb.DeleteResponse); + */ + delete(input: DeleteRequest, options?: RpcOptions): UnaryCall; + /** + * count get count of keys + * + * @generated from protobuf rpc: count(sessionstorepb.CountRequest) returns (sessionstorepb.CountResponse); + */ + count(input: CountRequest, options?: RpcOptions): UnaryCall; +} +// metadata token -> session id, room id, user id, username + +// open is used for presence + +// change stream will return all keys in order of oldest to newsest. + +// max number of keys -> 5000 +// max size per key -> 10240 Bytes + +/** + * @generated from protobuf service sessionstorepb.Store + */ +export class StoreClient implements IStoreClient, ServiceInfo { + typeName = Store.typeName; + methods = Store.methods; + options = Store.options; + constructor(private readonly _transport: RpcTransport) {} + /** + * open - start listening to updates in keys with provided match patterns + * provide change_id as last received ID to resume updates + * + * @generated from protobuf rpc: open(sessionstorepb.OpenRequest) returns (stream sessionstorepb.ChangeStream); + */ + open(input: OpenRequest, options?: RpcOptions): ServerStreamingCall { + const method = this.methods[0], + opt = this._transport.mergeOptions(options); + return stackIntercept('serverStreaming', this._transport, method, opt, input); + } + /** + * get last stored value in given key + * + * @generated from protobuf rpc: get(sessionstorepb.GetRequest) returns (sessionstorepb.GetResponse); + */ + get(input: GetRequest, options?: RpcOptions): UnaryCall { + const method = this.methods[1], + opt = this._transport.mergeOptions(options); + return stackIntercept('unary', this._transport, method, opt, input); + } + /** + * set key value + * + * @generated from protobuf rpc: set(sessionstorepb.SetRequest) returns (sessionstorepb.SetResponse); + */ + set(input: SetRequest, options?: RpcOptions): UnaryCall { + const method = this.methods[2], + opt = this._transport.mergeOptions(options); + return stackIntercept('unary', this._transport, method, opt, input); + } + /** + * delete key from store + * + * @generated from protobuf rpc: delete(sessionstorepb.DeleteRequest) returns (sessionstorepb.DeleteResponse); + */ + delete(input: DeleteRequest, options?: RpcOptions): UnaryCall { + const method = this.methods[3], + opt = this._transport.mergeOptions(options); + return stackIntercept('unary', this._transport, method, opt, input); + } + /** + * count get count of keys + * + * @generated from protobuf rpc: count(sessionstorepb.CountRequest) returns (sessionstorepb.CountResponse); + */ + count(input: CountRequest, options?: RpcOptions): UnaryCall { + const method = this.methods[4], + opt = this._transport.mergeOptions(options); + return stackIntercept('unary', this._transport, method, opt, input); + } +} diff --git a/packages/hms-whiteboard/src/grpc/sessionstore.ts b/packages/hms-whiteboard/src/grpc/sessionstore.ts new file mode 100644 index 0000000000..62c29f3d98 --- /dev/null +++ b/packages/hms-whiteboard/src/grpc/sessionstore.ts @@ -0,0 +1,1128 @@ +// @generated by protobuf-ts 2.9.4 with parameter long_type_string +// @generated from protobuf file "sessionstore.proto" (package "sessionstorepb", syntax proto3) +// tslint:disable +import type { + BinaryReadOptions, + BinaryWriteOptions, + IBinaryReader, + IBinaryWriter, + PartialMessage, +} from '@protobuf-ts/runtime'; +import { MessageType, UnknownFieldHandler, WireType, reflectionMergePartial } from '@protobuf-ts/runtime'; +import { ServiceType } from '@protobuf-ts/runtime-rpc'; +/** + * @generated from protobuf message sessionstorepb.HelloRequest + */ +export interface HelloRequest { + /** + * @generated from protobuf field: string name = 1; + */ + name: string; +} +/** + * @generated from protobuf message sessionstorepb.HelloResponse + */ +export interface HelloResponse { + /** + * @generated from protobuf field: string response = 1; + */ + response: string; +} +/** + * @generated from protobuf message sessionstorepb.SubscribeRequest + */ +export interface SubscribeRequest { + /** + * @generated from protobuf field: string name = 1; + */ + name: string; + /** + * @generated from protobuf field: int64 offset = 2; + */ + offset: string; +} +/** + * @generated from protobuf message sessionstorepb.Event + */ +export interface Event { + /** + * @generated from protobuf field: string message = 1; + */ + message: string; + /** + * @generated from protobuf field: int64 sequence = 2; + */ + sequence: string; +} +/** + * define new structure for value based on client needs and add support in + * following message + * + * @generated from protobuf message sessionstorepb.Value + */ +export interface Value { + /** + * @generated from protobuf field: sessionstorepb.Value.Type type = 1; + */ + type: Value_Type; + /** + * @generated from protobuf oneof: Data + */ + data: + | { + oneofKind: 'number'; + /** + * @generated from protobuf field: int64 number = 2; + */ + number: string; + } + | { + oneofKind: 'float'; + /** + * @generated from protobuf field: float float = 3; + */ + float: number; + } + | { + oneofKind: 'str'; + /** + * @generated from protobuf field: string str = 4; + */ + str: string; + } + | { + oneofKind: 'rawBytes'; + /** + * @generated from protobuf field: bytes raw_bytes = 5; + */ + rawBytes: Uint8Array; + } + | { + oneofKind: undefined; + }; +} +/** + * @generated from protobuf enum sessionstorepb.Value.Type + */ +export enum Value_Type { + /** + * @generated from protobuf enum value: NONE = 0; + */ + NONE = 0, + /** + * @generated from protobuf enum value: BYTES = 1; + */ + BYTES = 1, + /** + * @generated from protobuf enum value: STRING = 2; + */ + STRING = 2, + /** + * @generated from protobuf enum value: INTEGER = 3; + */ + INTEGER = 3, + /** + * @generated from protobuf enum value: FLOAT = 4; + */ + FLOAT = 4, +} +/** + * @generated from protobuf message sessionstorepb.GetRequest + */ +export interface GetRequest { + /** + * @generated from protobuf field: string key = 1; + */ + key: string; +} +/** + * @generated from protobuf message sessionstorepb.GetResponse + */ +export interface GetResponse { + /** + * @generated from protobuf field: string key = 1; + */ + key: string; + /** + * @generated from protobuf field: string namespace = 2; + */ + namespace: string; + /** + * @generated from protobuf field: sessionstorepb.Value value = 3; + */ + value?: Value; +} +/** + * @generated from protobuf message sessionstorepb.DeleteRequest + */ +export interface DeleteRequest { + /** + * @generated from protobuf field: string key = 1; + */ + key: string; +} +/** + * @generated from protobuf message sessionstorepb.DeleteResponse + */ +export interface DeleteResponse {} +/** + * @generated from protobuf message sessionstorepb.SetRequest + */ +export interface SetRequest { + /** + * @generated from protobuf field: string key = 1; + */ + key: string; + /** + * @generated from protobuf field: sessionstorepb.Value value = 3; + */ + value?: Value; +} +/** + * @generated from protobuf message sessionstorepb.SetResponse + */ +export interface SetResponse {} +/** + * @generated from protobuf message sessionstorepb.ChangeStream + */ +export interface ChangeStream { + /** + * @generated from protobuf field: string change_id = 1; + */ + changeId: string; + /** + * @generated from protobuf field: string key = 2; + */ + key: string; + /** + * @generated from protobuf field: string namespace = 3; + */ + namespace: string; + /** + * @generated from protobuf field: sessionstorepb.Value value = 4; + */ + value?: Value; + /** + * @generated from protobuf field: string from_id = 5; + */ + fromId: string; +} +/** + * @generated from protobuf message sessionstorepb.Select + */ +export interface Select { + /** + * @generated from protobuf oneof: match + */ + match: + | { + oneofKind: 'all'; + /** + * @generated from protobuf field: string all = 1; + */ + all: string; // match all keys + } + | { + oneofKind: 'key'; + /** + * @generated from protobuf field: string key = 2; + */ + key: string; // match key + } + | { + oneofKind: 'prefix'; + /** + * @generated from protobuf field: string prefix = 3; + */ + prefix: string; // match keys with given prefix + } + | { + oneofKind: 'suffix'; + /** + * @generated from protobuf field: string suffix = 4; + */ + suffix: string; // match keys with given suffix + } + | { + oneofKind: undefined; + }; +} +/** + * @generated from protobuf message sessionstorepb.OpenRequest + */ +export interface OpenRequest { + /** + * last received change_id for reconnection, "" if first connection + * + * @generated from protobuf field: string change_id = 1; + */ + changeId: string; + /** + * @generated from protobuf field: repeated sessionstorepb.Select select = 3; + */ + select: Select[]; +} +/** + * @generated from protobuf message sessionstorepb.CountRequest + */ +export interface CountRequest {} +/** + * @generated from protobuf message sessionstorepb.CountResponse + */ +export interface CountResponse { + /** + * @generated from protobuf field: int64 count = 1; + */ + count: string; +} +// @generated message type with reflection information, may provide speed optimized methods +class HelloRequest$Type extends MessageType { + constructor() { + super('sessionstorepb.HelloRequest', [{ no: 1, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }]); + } + create(value?: PartialMessage): HelloRequest { + const message = globalThis.Object.create(this.messagePrototype!); + message.name = ''; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: HelloRequest, + ): HelloRequest { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string name */ 1: + message.name = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: HelloRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string name = 1; */ + if (message.name !== '') writer.tag(1, WireType.LengthDelimited).string(message.name); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.HelloRequest + */ +export const HelloRequest = new HelloRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class HelloResponse$Type extends MessageType { + constructor() { + super('sessionstorepb.HelloResponse', [{ no: 1, name: 'response', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }]); + } + create(value?: PartialMessage): HelloResponse { + const message = globalThis.Object.create(this.messagePrototype!); + message.response = ''; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: HelloResponse, + ): HelloResponse { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string response */ 1: + message.response = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: HelloResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string response = 1; */ + if (message.response !== '') writer.tag(1, WireType.LengthDelimited).string(message.response); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.HelloResponse + */ +export const HelloResponse = new HelloResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SubscribeRequest$Type extends MessageType { + constructor() { + super('sessionstorepb.SubscribeRequest', [ + { no: 1, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: 'offset', kind: 'scalar', T: 3 /*ScalarType.INT64*/ }, + ]); + } + create(value?: PartialMessage): SubscribeRequest { + const message = globalThis.Object.create(this.messagePrototype!); + message.name = ''; + message.offset = '0'; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: SubscribeRequest, + ): SubscribeRequest { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string name */ 1: + message.name = reader.string(); + break; + case /* int64 offset */ 2: + message.offset = reader.int64().toString(); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: SubscribeRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string name = 1; */ + if (message.name !== '') writer.tag(1, WireType.LengthDelimited).string(message.name); + /* int64 offset = 2; */ + if (message.offset !== '0') writer.tag(2, WireType.Varint).int64(message.offset); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.SubscribeRequest + */ +export const SubscribeRequest = new SubscribeRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class Event$Type extends MessageType { + constructor() { + super('sessionstorepb.Event', [ + { no: 1, name: 'message', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: 'sequence', kind: 'scalar', T: 3 /*ScalarType.INT64*/ }, + ]); + } + create(value?: PartialMessage): Event { + const message = globalThis.Object.create(this.messagePrototype!); + message.message = ''; + message.sequence = '0'; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Event): Event { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string message */ 1: + message.message = reader.string(); + break; + case /* int64 sequence */ 2: + message.sequence = reader.int64().toString(); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: Event, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string message = 1; */ + if (message.message !== '') writer.tag(1, WireType.LengthDelimited).string(message.message); + /* int64 sequence = 2; */ + if (message.sequence !== '0') writer.tag(2, WireType.Varint).int64(message.sequence); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.Event + */ +export const Event = new Event$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class Value$Type extends MessageType { + constructor() { + super('sessionstorepb.Value', [ + { no: 1, name: 'type', kind: 'enum', T: () => ['sessionstorepb.Value.Type', Value_Type] }, + { no: 2, name: 'number', kind: 'scalar', oneof: 'data', T: 3 /*ScalarType.INT64*/ }, + { no: 3, name: 'float', kind: 'scalar', oneof: 'data', T: 2 /*ScalarType.FLOAT*/ }, + { no: 4, name: 'str', kind: 'scalar', oneof: 'data', T: 9 /*ScalarType.STRING*/ }, + { no: 5, name: 'raw_bytes', kind: 'scalar', oneof: 'data', T: 12 /*ScalarType.BYTES*/ }, + ]); + } + create(value?: PartialMessage): Value { + const message = globalThis.Object.create(this.messagePrototype!); + message.type = 0; + message.data = { oneofKind: undefined }; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Value): Value { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* sessionstorepb.Value.Type type */ 1: + message.type = reader.int32(); + break; + case /* int64 number */ 2: + message.data = { + oneofKind: 'number', + number: reader.int64().toString(), + }; + break; + case /* float float */ 3: + message.data = { + oneofKind: 'float', + float: reader.float(), + }; + break; + case /* string str */ 4: + message.data = { + oneofKind: 'str', + str: reader.string(), + }; + break; + case /* bytes raw_bytes */ 5: + message.data = { + oneofKind: 'rawBytes', + rawBytes: reader.bytes(), + }; + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: Value, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* sessionstorepb.Value.Type type = 1; */ + if (message.type !== 0) writer.tag(1, WireType.Varint).int32(message.type); + /* int64 number = 2; */ + if (message.data.oneofKind === 'number') writer.tag(2, WireType.Varint).int64(message.data.number); + /* float float = 3; */ + if (message.data.oneofKind === 'float') writer.tag(3, WireType.Bit32).float(message.data.float); + /* string str = 4; */ + if (message.data.oneofKind === 'str') writer.tag(4, WireType.LengthDelimited).string(message.data.str); + /* bytes raw_bytes = 5; */ + if (message.data.oneofKind === 'rawBytes') writer.tag(5, WireType.LengthDelimited).bytes(message.data.rawBytes); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.Value + */ +export const Value = new Value$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetRequest$Type extends MessageType { + constructor() { + super('sessionstorepb.GetRequest', [{ no: 1, name: 'key', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }]); + } + create(value?: PartialMessage): GetRequest { + const message = globalThis.Object.create(this.messagePrototype!); + message.key = ''; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: GetRequest, + ): GetRequest { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string key */ 1: + message.key = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string key = 1; */ + if (message.key !== '') writer.tag(1, WireType.LengthDelimited).string(message.key); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.GetRequest + */ +export const GetRequest = new GetRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class GetResponse$Type extends MessageType { + constructor() { + super('sessionstorepb.GetResponse', [ + { no: 1, name: 'key', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: 'namespace', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: 'value', kind: 'message', T: () => Value }, + ]); + } + create(value?: PartialMessage): GetResponse { + const message = globalThis.Object.create(this.messagePrototype!); + message.key = ''; + message.namespace = ''; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: GetResponse, + ): GetResponse { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string key */ 1: + message.key = reader.string(); + break; + case /* string namespace */ 2: + message.namespace = reader.string(); + break; + case /* sessionstorepb.Value value */ 3: + message.value = Value.internalBinaryRead(reader, reader.uint32(), options, message.value); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: GetResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string key = 1; */ + if (message.key !== '') writer.tag(1, WireType.LengthDelimited).string(message.key); + /* string namespace = 2; */ + if (message.namespace !== '') writer.tag(2, WireType.LengthDelimited).string(message.namespace); + /* sessionstorepb.Value value = 3; */ + if (message.value) + Value.internalBinaryWrite(message.value, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.GetResponse + */ +export const GetResponse = new GetResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeleteRequest$Type extends MessageType { + constructor() { + super('sessionstorepb.DeleteRequest', [{ no: 1, name: 'key', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }]); + } + create(value?: PartialMessage): DeleteRequest { + const message = globalThis.Object.create(this.messagePrototype!); + message.key = ''; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: DeleteRequest, + ): DeleteRequest { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string key */ 1: + message.key = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: DeleteRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string key = 1; */ + if (message.key !== '') writer.tag(1, WireType.LengthDelimited).string(message.key); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.DeleteRequest + */ +export const DeleteRequest = new DeleteRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class DeleteResponse$Type extends MessageType { + constructor() { + super('sessionstorepb.DeleteResponse', []); + } + create(value?: PartialMessage): DeleteResponse { + const message = globalThis.Object.create(this.messagePrototype!); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: DeleteResponse, + ): DeleteResponse { + return target ?? this.create(); + } + internalBinaryWrite(message: DeleteResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.DeleteResponse + */ +export const DeleteResponse = new DeleteResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SetRequest$Type extends MessageType { + constructor() { + super('sessionstorepb.SetRequest', [ + { no: 1, name: 'key', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: 'value', kind: 'message', T: () => Value }, + ]); + } + create(value?: PartialMessage): SetRequest { + const message = globalThis.Object.create(this.messagePrototype!); + message.key = ''; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: SetRequest, + ): SetRequest { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string key */ 1: + message.key = reader.string(); + break; + case /* sessionstorepb.Value value */ 3: + message.value = Value.internalBinaryRead(reader, reader.uint32(), options, message.value); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: SetRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string key = 1; */ + if (message.key !== '') writer.tag(1, WireType.LengthDelimited).string(message.key); + /* sessionstorepb.Value value = 3; */ + if (message.value) + Value.internalBinaryWrite(message.value, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.SetRequest + */ +export const SetRequest = new SetRequest$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class SetResponse$Type extends MessageType { + constructor() { + super('sessionstorepb.SetResponse', []); + } + create(value?: PartialMessage): SetResponse { + const message = globalThis.Object.create(this.messagePrototype!); + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: SetResponse, + ): SetResponse { + return target ?? this.create(); + } + internalBinaryWrite(message: SetResponse, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.SetResponse + */ +export const SetResponse = new SetResponse$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class ChangeStream$Type extends MessageType { + constructor() { + super('sessionstorepb.ChangeStream', [ + { no: 1, name: 'change_id', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + { no: 2, name: 'key', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + { no: 3, name: 'namespace', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + { no: 4, name: 'value', kind: 'message', T: () => Value }, + { no: 5, name: 'from_id', kind: 'scalar', T: 9 /*ScalarType.STRING*/ }, + ]); + } + create(value?: PartialMessage): ChangeStream { + const message = globalThis.Object.create(this.messagePrototype!); + message.changeId = ''; + message.key = ''; + message.namespace = ''; + message.fromId = ''; + if (value !== undefined) reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead( + reader: IBinaryReader, + length: number, + options: BinaryReadOptions, + target?: ChangeStream, + ): ChangeStream { + let message = target ?? this.create(), + end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* string change_id */ 1: + message.changeId = reader.string(); + break; + case /* string key */ 2: + message.key = reader.string(); + break; + case /* string namespace */ 3: + message.namespace = reader.string(); + break; + case /* sessionstorepb.Value value */ 4: + message.value = Value.internalBinaryRead(reader, reader.uint32(), options, message.value); + break; + case /* string from_id */ 5: + message.fromId = reader.string(); + break; + default: + let u = options.readUnknownField; + if (u === 'throw') + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: ChangeStream, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* string change_id = 1; */ + if (message.changeId !== '') writer.tag(1, WireType.LengthDelimited).string(message.changeId); + /* string key = 2; */ + if (message.key !== '') writer.tag(2, WireType.LengthDelimited).string(message.key); + /* string namespace = 3; */ + if (message.namespace !== '') writer.tag(3, WireType.LengthDelimited).string(message.namespace); + /* sessionstorepb.Value value = 4; */ + if (message.value) + Value.internalBinaryWrite(message.value, writer.tag(4, WireType.LengthDelimited).fork(), options).join(); + /* string from_id = 5; */ + if (message.fromId !== '') writer.tag(5, WireType.LengthDelimited).string(message.fromId); + let u = options.writeUnknownFields; + if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message sessionstorepb.ChangeStream + */ +export const ChangeStream = new ChangeStream$Type(); +// @generated message type with reflection information, may provide speed optimized methods +class Select$Type extends MessageType): Select { + const message = globalThis.Object.create(this.messagePrototype!); + message.match = { oneofKind: undefined }; + if (value !== undefined) reflectionMergePartial