@collective-intelligence/external-apps-client-sdk-react 0.1.38 → 0.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ import{createEntityHttpTransport,createResourceClient}from"@collective-intelligence/external-apps-client-sdk";import{useQueryClient}from"@tanstack/react-query";import*as ManagedRuntime from"effect/ManagedRuntime";import{createContext,useContext,useLayoutEffect,useMemo,useSyncExternalStore}from"react";import{queryOptions}from"@tanstack/react-query";var rootKey=["ci-resources"];var resourceKeys={all:rootKey,list:(organizationId,resourceId,version,query)=>[...resourceKeys.lists(organizationId,resourceId,version),query],lists:(organizationId,resourceId,version)=>[...resourceKeys.resource(organizationId,resourceId,version),"lists"],organization:(organizationId)=>[...rootKey,"organizations",organizationId],record:(organizationId,resourceId,version,recordId,includeDeleted=false)=>[...resourceKeys.records(organizationId,resourceId,version),recordId,includeDeleted],records:(organizationId,resourceId,version)=>[...resourceKeys.resource(organizationId,resourceId,version),"records"],resource:(organizationId,resourceId,version)=>[...resourceKeys.organization(organizationId),"resources",resourceId,"versions",version]};class ResourceQueryError2 extends Error{correlationId;resourceError;constructor(correlationId,error){super(error.message);this.name="ResourceQueryError";this.correlationId=correlationId;this.resourceError=error}}var unwrapResourceResult2=(result)=>{if(!result.ok){throw new ResourceQueryError2(result.correlationId,result.error)}return result.value};var createResourceListQueryOptions=(options)=>queryOptions({queryFn:async({signal})=>unwrapResourceResult2(await options.client.list(options.query,{signal})),queryKey:resourceKeys.list(options.organizationId,options.client.definition.id,options.client.definition.version,options.query)});var mapResourceAuthState2=(source)=>{if("ok"in source){if(source.ok){return{status:"authenticated"}}if(source.error.code==="forbidden"){return{status:"forbidden"}}if(source.error.code==="unauthenticated"){return{status:"unauthenticated"}}return{status:"authenticated"}}if(source.status==="authenticated"){return{status:"authenticated"}}if(source.status==="expired"){return{status:"expired"}}if(source.status==="error"&&source.error.code==="reauthorization_required"){return{status:"reauthentication_required"}}return{status:"unauthenticated"}};var hasResourceCapability2=(capabilities,capability)=>capabilities[capability]===true;var clearProtectedResourceQueries=async(queryClient,organizationId)=>{const queryKey=organizationId===undefined?resourceKeys.all:resourceKeys.organization(organizationId);await queryClient.cancelQueries({queryKey});queryClient.removeQueries({queryKey})};import{hashKey}from"@tanstack/react-query";import*as Context from"effect/Context";import*as Effect from"effect/Effect";import*as Layer from"effect/Layer";import*as RcMap from"effect/RcMap";import*as Semaphore from"effect/Semaphore";class WriteLock extends Context.Service()("@collective-intelligence/external-apps-client-sdk-react/WriteLock"){}var idleTimeToLive="30 seconds";var layer=Layer.effect(WriteLock,Effect.gen(function*makeWriteLock(){const locks=yield*RcMap.make({idleTimeToLive,lookup:(_hash)=>Semaphore.make(1)});const holding=(hash)=>(self)=>Effect.scoped(Effect.flatMap(RcMap.get(locks,hash),(lock)=>lock.withPermits(1)(self)));return WriteLock.of({settled:(queryKey)=>Effect.flatMap(RcMap.keys(locks),(hashes)=>{const hash=hashKey(queryKey);const below=`${hash.slice(0,-1)},`;return Effect.forEach([...hashes].filter((held)=>held===hash||held.startsWith(below)),(held)=>holding(held)(Effect.void),{discard:true})}),withRecord:(recordKey)=>holding(hashKey(recordKey))})}));var writesSettled=(queryKey)=>Effect.gen(function*awaitWrites(){const lock=yield*WriteLock;yield*lock.settled(queryKey)});import{jsx}from"react/jsx-runtime";var entityScopeError=(outcome="not_dispatched")=>new ResourceQueryError2("client-scope",{code:"unauthenticated",message:"The authenticated entity source has changed",outcome,retryable:false});var identityKey=(state)=>state.status==="authenticated"?[state.identity.sourceId,state.identity.applicationId,state.identity.userId,state.identity.organizationId]:[state.status];var EntityContext=createContext(null);var createRuntime=(source,state)=>{let active=true;let onWriteFailed;return{activate:()=>{active=true},current:()=>active&&source.getSnapshot()===state&&state.status==="authenticated",deactivate:()=>{active=false},formScope:globalThis.crypto.randomUUID(),key:identityKey(state),reportWriteFailures:(listener)=>{onWriteFailed=listener},source,state,writeFailed:(event)=>{onWriteFailed?.(event)},writeLock:ManagedRuntime.make(layer)}};var EntityRuntimeProvider=({source,onWriteFailed,children})=>{const queryClient=useQueryClient();const state=useSyncExternalStore(source.subscribe,source.getSnapshot,source.getSnapshot);const runtime=useMemo(()=>createRuntime(source,state),[source,state]);useLayoutEffect(()=>{runtime.reportWriteFailures(onWriteFailed)},[runtime,onWriteFailed]);useLayoutEffect(()=>{runtime.activate();return()=>{runtime.deactivate();queryClient.cancelQueries({queryKey:["ci-entities",...runtime.key]});queryClient.removeQueries({queryKey:["ci-entities",...runtime.key]})}},[queryClient,runtime]);return jsx(EntityContext.Provider,{value:runtime,children})};var useEntityRuntime=()=>{const context=useContext(EntityContext);if(context===null){throw new Error("Configure an entity source on CollectiveIntelligenceProvider")}return context};var defaultPathFor=(contract)=>`/api/resources/${contract.id}`;var createDelegatedEntitySource2=(options)=>{const fetch=options.fetch??globalThis.fetch;const pathFor=options.pathFor??defaultPathFor;const sourceId=options.sourceId??`${options.origin}/api/resources`;let cached;const snapshot=()=>{const identity=options.getIdentity();const status=options.getStatus();const next=status==="authenticated"&&identity!==null?{identity:{applicationId:options.applicationId,organizationId:identity.organizationId,sourceId,userId:identity.userId},status:"authenticated"}:{status:status==="expired"?"expired":"unauthenticated"};if(cached!==undefined&&identityKey(cached).join("\x00")===identityKey(next).join("\x00")){return cached}cached=next;return next};return{bind:(contract)=>createResourceClient({definition:contract,protocol:"entity",transport:createEntityHttpTransport({authentication:{credentials:"same-origin",mode:"server_delegated"},destination:{endpoint:new URL(pathFor(contract),options.origin).href,kind:"gateway"},fetch})}),getSnapshot:snapshot,subscribe:options.subscribe}};var assertConfiguredFields=(config)=>{const declared=new Set(Object.keys(config.fields));const referenced=[...config.table.columns,...Object.values(config.table.variants??{}).flatMap((variant)=>variant.columns),config.list.title,...config.list.description===undefined?[]:[config.list.description],...config.forms.create.fields,...config.forms.update.fields];const unknown=referenced.find((field)=>!declared.has(field));if(unknown!==undefined){throw new Error(`Entity view references unconfigured field: ${unknown}`)}};var defineEntity2=(declaration)=>{assertConfiguredFields(declaration.config);const schemaFields=new Set(Object.keys(declaration.contract.schemas.entity.properties??{}));const unknown=Object.keys(declaration.config.fields).find((field)=>!schemaFields.has(field));if(unknown!==undefined){throw new Error(`Configured field is absent from the entity schema: ${unknown}`)}return Object.freeze(declaration)};import{ResourceFilterPrimitive,ResourceFiltersBar,ResourceFormPrimitive,ResourceListPrimitive,ResourcePaginationPrimitive,ResourceTablePrimitive}from"@collective-intelligence/ui-react/resources";import{useMemo as useMemo5,useState as useState2}from"react";import{useIsMutating,useMutation,useQueryClient as useQueryClient2}from"@tanstack/react-query";import{useMemo as useMemo2,useRef}from"react";import{CiError,CiErrorCode,CiTransportError}from"@collective-intelligence/external-apps-client-sdk/effect";import*as Effect2 from"effect/Effect";import*as Exit from"effect/Exit";import*as Schema from"effect/Schema";var heldWrites=new WeakMap;var fetchedOrder=new WeakMap;var orderOf=(page)=>fetchedOrder.get(page)??page.items.map((row)=>row.id);var withOrder=(page,order)=>{fetchedOrder.set(page,order);return page};var store=(queryClient,key,data,next,write,holds)=>{const writes=new Set(heldWrites.get(data));if(holds){writes.add(write)}else{writes.delete(write)}const stored=next===data?data:queryClient.setQueryData(key,next);if(stored!==undefined){heldWrites.set(stored,writes);const order=fetchedOrder.get(next)??fetchedOrder.get(data);if(order!==undefined){fetchedOrder.set(stored,order)}}};var touch=(queryClient,key,snapshot,edit,write,optimistic)=>{store(queryClient,key,snapshot,optimistic?edit.pending(snapshot):snapshot,write,true);return(confirmed)=>{const data=queryClient.getQueryData(key);if(data!==undefined&&heldWrites.get(data)?.has(write)===true){store(queryClient,key,data,edit.settled(data,snapshot,confirmed),write,false)}}};var predicted=(change,record)=>change.operation==="update"?{...record,value:{...record.value,...change.input.value}}:{...record,deletedAt:new Date().toISOString()};var pendingRow=(input)=>({id:input.idempotencyKey,revision:"",value:input.value});var replaceItem=(page,id,replace)=>page.items.some((item)=>item.id===id)?{...page,items:page.items.map((item)=>item.id===id?replace(item):item)}:page;var removeItem=(page,id)=>page.items.some((item)=>item.id===id)?{...page,items:page.items.filter((item)=>item.id!==id)}:page;var idsAfter=(ids,id)=>{const index=ids.indexOf(id);return index===-1?[]:ids.slice(index+1)};var restoreItem=(page,snapshot,id)=>{const item=snapshot.items.find((row)=>row.id===id);if(item===undefined||page.items.some((row)=>row.id===id)){return page}const later=new Set(idsAfter(orderOf(page),id));const at=page.items.findIndex((row)=>later.has(row.id));const items=[...page.items];items.splice(at===-1?items.length:at,0,item);return{...page,items}};var pageEdit=(change)=>{if(change.operation==="update"){const{id}=change.input;return{pending:(page)=>replaceItem(page,id,(item)=>predicted(change,item)),settled:(page,snapshot,confirmed)=>replaceItem(page,id,(item)=>confirmed??snapshot.items.find((row)=>row.id===id)??item)}}if(change.operation==="delete"){const{id}=change.input;return{pending:(page)=>removeItem(page,id),settled:(page,snapshot,confirmed)=>confirmed===undefined?restoreItem(page,snapshot,id):removeItem(page,id)}}const key=change.input.idempotencyKey;const first=(page,row)=>page.page===1?withOrder({...page,items:[row,...page.items]},[row.id,...orderOf(page)]):page;return{pending:(page)=>first(page,pendingRow(change.input)),settled:(page,_snapshot,confirmed)=>{if(!page.items.some((item)=>item.id===key)){return confirmed===undefined?page:first(page,confirmed)}const order=orderOf(page);return confirmed===undefined?withOrder(removeItem(page,key),order.filter((id)=>id!==key)):withOrder(replaceItem(page,key,()=>confirmed),order.map((id)=>id===key?confirmed.id:id))}}};var recordKeyOf=(resourceKey,change)=>[...resourceKey,"record",change.operation==="create"?change.input.idempotencyKey:change.input.id];var apply=(options,recordKey,write)=>{const{change,optimistic,queryClient,resourceKey}=options;const settles=[];if(change.operation!=="create"){const record=queryClient.getQueryData(recordKey);if(record!==undefined){settles.push(touch(queryClient,recordKey,record,{pending:(data)=>predicted(change,data),settled:(_data,snapshot,confirmed)=>confirmed??snapshot},write,optimistic))}}for(const[key,page]of queryClient.getQueriesData({queryKey:[...resourceKey,"list"]})){if(page!==undefined){fetchedOrder.set(page,orderOf(page));settles.push(touch(queryClient,key,page,pageEdit(change),write,optimistic))}}return settles};var isCiErrorCode=Schema.is(CiErrorCode);var failure=(error)=>error.code==="transport_error"?new CiTransportError({cause:error}):new CiError({code:isCiErrorCode(error.code)?error.code:"invalid_request",details:error.outcome===undefined?{...error.details,resourceCode:error.code}:{...error.details,outcome:error.outcome,resourceCode:error.code},message:error.message,retryable:error.retryable});var inScope=(current)=>Effect2.suspend(()=>current()?Effect2.void:Effect2.fail(entityScopeError()));var write=(options)=>Effect2.gen(function*optimisticWrite(){const lock=yield*WriteLock;const{queryClient,resourceKey}=options;const recordKey=recordKeyOf(resourceKey,options.change);const token=Symbol("optimistic write");return yield*lock.withRecord(recordKey)(Effect2.acquireUseRelease(Effect2.gen(function*acquire(){yield*inScope(options.current);yield*Effect2.promise(()=>Promise.all([queryClient.cancelQueries({exact:true,queryKey:recordKey}),queryClient.cancelQueries({queryKey:[...resourceKey,"list"]})]));yield*inScope(options.current);return apply(options,recordKey,token)}),()=>Effect2.promise(options.execute),(settles,exit)=>Effect2.sync(()=>{const result=Exit.isSuccess(exit)?exit.value:undefined;const confirmed=result?.ok===true?result.value:undefined;for(const settle of settles){settle(confirmed)}if(result?.ok===false&&options.current()){options.onWriteFailed({error:failure(result.error),label:options.label,operation:options.change.operation})}})))}).pipe(Effect2.ensuring(Effect2.sync(()=>{if(options.current()){options.queryClient.invalidateQueries({queryKey:options.resourceKey})}})));var immutable=(value)=>{if(value!==null&&typeof value==="object"){for(const child of Object.values(value)){immutable(child)}Object.freeze(value)}return value};var useEntityMutation=(contract,options)=>{const runtime=useEntityRuntime();const queryClient=useQueryClient2();const client=useMemo2(()=>runtime.source.bind(contract),[runtime,contract]);const resourceKey=["ci-entities",...runtime.key,contract.id,contract.version];const mutationKey=[...resourceKey,"write",options.id??"create"];const lastAction=useRef(null);const scopeOptions={};if(options.id!==undefined){scopeOptions.scope={id:JSON.stringify(mutationKey)}}const mutation=useMutation({mutationKey,...scopeOptions,mutationFn:async(action)=>{if(!action.current()){throw entityScopeError()}const result=await action.execute();if(!action.current()){throw entityScopeError("uncertain")}if(!result.ok){throw new ResourceQueryError2(result.correlationId,result.error)}return result},networkMode:"always",retry:false});const pending=useIsMutating({mutationKey})>0;const send=async(action)=>{try{const result=await mutation.mutateAsync(action);if(!action.current()){const error=entityScopeError("uncertain");return{correlationId:error.correlationId,error:error.resourceError,ok:false}}return result}catch(error){if(error instanceof ResourceQueryError2){return{correlationId:error.correlationId,error:error.resourceError,ok:false}}throw error}};const submit=(input)=>{const captured=immutable(structuredClone(options.prepare(input)));const action={current:runtime.current,execute:()=>runtime.writeLock.runPromise(write({change:options.change(captured),current:runtime.current,execute:()=>options.execute(client,captured),label:contract.id,onWriteFailed:runtime.writeFailed,optimistic:options.optimistic??true,queryClient,resourceKey})),input:captured,runtime,target:options.id};lastAction.current=action;return send(action)};const resubmit=()=>{const action=lastAction.current;if(action===null){throw new Error("No submitted entity action to resubmit")}if(action.target!==options.id){throw new Error("The submitted action belongs to a different record")}return send(action)};const current=mutation.variables===undefined||mutation.variables.runtime===runtime&&mutation.variables.target===options.id&&mutation.variables.current();const error=current&&mutation.error instanceof ResourceQueryError2?mutation.error:null;const failureStatus=()=>{if(error?.resourceError.outcome==="uncertain"){return"uncertain"}if(error?.resourceError.code==="conflict"){return"conflict"}return"rejected"};const status=mutation.isError?failureStatus():mutation.status;return{available:runtime.state.status==="authenticated"&&client.definition.capabilities[options.operation]===true,data:current?mutation.data?.value:undefined,error,pending,resubmit,status:current?status:"idle",submit,submitted:current?mutation.variables?.input:undefined}};var useEntityUpdate2=(contract,target)=>useEntityMutation(contract,{change:(input)=>({input,operation:"update"}),execute:(client,input)=>client.update(input),id:target.id,operation:"update",optimistic:target.optimistic,prepare:(input)=>({...input,id:target.id,idempotencyKey:globalThis.crypto.randomUUID()})});var useEntityCreate2=(contract)=>useEntityMutation(contract,{change:(input)=>({input,operation:"create"}),execute:(client,input)=>client.create(input),operation:"create",prepare:(input)=>({...input,idempotencyKey:globalThis.crypto.randomUUID()})});var useEntityDelete2=(contract,target)=>useEntityMutation(contract,{change:(input)=>({input,operation:"delete"}),execute:(client,input)=>client.delete(input),id:target.id,operation:"delete",optimistic:target.optimistic,prepare:(input)=>({...input,id:target.id,idempotencyKey:globalThis.crypto.randomUUID()})});import{useQuery}from"@tanstack/react-query";import{useMemo as useMemo3}from"react";var authStateForError=(error,state)=>{if(error instanceof ResourceQueryError2){if(error.resourceError.code==="forbidden"){return{status:"forbidden"}}if(error.resourceError.code==="unauthenticated"){return{status:"unauthenticated"}}}return state};var useEntityList2=(contract,query)=>{const runtime=useEntityRuntime();const client=useMemo3(()=>runtime.source.bind(contract),[runtime,contract]);const result=useQuery({enabled:runtime.state.status==="authenticated"&&client.definition.capabilities.search,queryFn:async({queryKey,signal})=>{if(!runtime.current()){throw entityScopeError()}await runtime.writeLock.runPromise(writesSettled(queryKey.slice(0,-2)),{signal});const data=unwrapResourceResult2(await client.list(query,{signal}));if(!runtime.current()){throw entityScopeError()}return data},queryKey:["ci-entities",...runtime.key,contract.id,contract.version,"list",query],retry:false});return{authState:authStateForError(result.error,runtime.state),capabilities:client.definition.capabilities,data:result.data,empty:result.data?.items.length===0,error:result.error,loading:result.isLoading,refresh:async()=>{await result.refetch()},refreshing:result.isFetching}};var useEntityRecord2=(contract,input)=>{const runtime=useEntityRuntime();const client=useMemo3(()=>runtime.source.bind(contract),[runtime,contract]);const result=useQuery({enabled:runtime.state.status==="authenticated"&&client.definition.capabilities.get===true,queryFn:async({queryKey,signal})=>{if(!runtime.current()){throw entityScopeError()}await runtime.writeLock.runPromise(writesSettled(queryKey),{signal});const data=unwrapResourceResult2(await client.get(input,{signal}));if(!runtime.current()){throw entityScopeError()}return data},queryKey:["ci-entities",...runtime.key,contract.id,contract.version,"record",input.id],retry:false});return{authState:authStateForError(result.error,runtime.state),capabilities:client.definition.capabilities,data:result.data,error:result.error,loading:result.isLoading,refresh:async()=>{await result.refetch()},refreshing:result.isFetching}};import{createEntityProtocol}from"@collective-intelligence/external-apps-client-sdk/resources";import{createParser,parseAsJson,useQueryStates}from"nuqs";import{useMemo as useMemo4,useState}from"react";var DEFAULT_PAGE_SIZE=25;var namespacePattern=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;var isObject=(value)=>typeof value==="object"&&value!==null&&!Array.isArray(value);var isFilter=(value)=>{if(!isObject(value)){return false}if((value.operator==="and"||value.operator==="or")&&"filters"in value){return Array.isArray(value.filters)&&value.filters.every(isFilter)}if(value.operator==="not"&&"filter"in value){return isFilter(value.filter)}return typeof value.field==="string"&&typeof value.operator==="string"&&(value.operator==="is_null"||value.operator==="is_not_null"||value.operator==="is_empty"||("value"in value))};var isSorts=(value)=>Array.isArray(value)&&value.every((sort)=>isObject(sort)&&typeof sort.field==="string"&&(sort.direction==="asc"||sort.direction==="desc"));var positiveInteger=(maximum=Number.MAX_SAFE_INTEGER)=>createParser({parse:(value)=>{const number=Number(value);return/^[1-9]\d*$/u.test(value)&&Number.isSafeInteger(number)&&number<=maximum?number:null},serialize:String});var pageSizeFor=(value=DEFAULT_PAGE_SIZE)=>Number.isSafeInteger(value)&&value>0&&value<=100?value:DEFAULT_PAGE_SIZE;var parsersFor=(pageSize,contract)=>{const protocol=contract===undefined?undefined:createEntityProtocol(contract);const accepts=(query)=>protocol===undefined||protocol.decodeRequest({operation:"list",query:{pagination:{mode:"page",page:1,pageSize},...query},requestId:"view-state",resourceId:contract?.id}).ok;return{filter:parseAsJson((value)=>isFilter(value)&&accepts({filter:value})?value:null),page:positiveInteger().withDefault(1),pageSize:positiveInteger(100).withDefault(pageSize),sort:parseAsJson((value)=>isSorts(value)&&accepts({sort:value})?value:null).withDefault([]),textSearch:createParser({parse:(value)=>accepts({textSearch:value})?value:null,serialize:(value)=>value}).withDefault("")}};var queryFor=(state)=>{const query={pagination:{mode:"page",page:state.page,pageSize:state.pageSize}};if(state.filter!==null){query.filter=state.filter}if(state.sort.length>0){query.sort=state.sort}if(state.textSearch.trim()!==""){query.textSearch=state.textSearch.trim()}return query};var controller=(state,update)=>({query:queryFor(state),setFilter:(filter)=>update({filter,page:1}),setPage:(page)=>update({page:Math.max(1,page)}),setPageSize:(pageSize)=>update({page:1,pageSize:Math.max(1,Math.min(100,pageSize))}),setSort:(sort)=>update({page:1,sort:[...sort]}),setTextSearch:(textSearch)=>update({page:1,textSearch}),state});var useEntityViewState2=(namespace,input={})=>{if(!namespacePattern.test(namespace)){throw new Error("URL-backed entity views require a stable alphanumeric namespace")}const parsers=useMemo4(()=>parsersFor(pageSizeFor(input.pageSize),input.contract),[input.pageSize,input.contract]);const[state,setState]=useQueryStates(parsers,{clearOnDefault:true,history:"replace",shallow:false,urlKeys:{filter:`${namespace}.filter`,page:`${namespace}.page`,pageSize:`${namespace}.pageSize`,sort:`${namespace}.sort`,textSearch:`${namespace}.textSearch`}});const normalized=useMemo4(()=>({filter:state.filter,page:state.page>0?state.page:1,pageSize:state.pageSize>0&&state.pageSize<=100?state.pageSize:input.pageSize??DEFAULT_PAGE_SIZE,sort:state.sort,textSearch:state.textSearch}),[input.pageSize,state]);return controller(normalized,(next)=>{const{sort,...values}=next;const update=values;if(sort!==undefined){update.sort=[...sort]}setState(update)})};var useMemoryEntityViewState2=(input={})=>{const[state,setState]=useState({filter:null,page:1,pageSize:pageSizeFor(input.pageSize),sort:[],textSearch:""});return controller(state,(next)=>{setState((current)=>({...current,...next}))})};import{jsx as jsx2,jsxs,Fragment}from"react/jsx-runtime";var isObject2=(value)=>value!==null&&typeof value==="object"&&!Array.isArray(value);var schemaProperties=(entity,mode="entity")=>{const properties=entity.contract.schemas[mode]?.properties;return isObject2(properties)?properties:{}};var requiredFields=(entity,mode)=>{const required=entity.contract.schemas[mode]?.required;return new Set(Array.isArray(required)?required.filter((value)=>typeof value==="string"):[])};var scalarTypes=(schema)=>{const{type}=schema;if(typeof type==="string"){return[type]}return Array.isArray(type)?type.filter((value)=>typeof value==="string"):[]};var presentationSchema=(schema)=>{const union=schema.anyOf??schema.oneOf;if(!Array.isArray(union)){return schema}const members=union.filter(isObject2);const values=members.filter((member)=>member.type!=="null");const[value]=values;if(members.length===2&&values.length===1&&value!==undefined){return{...schema,...value,type:[...scalarTypes(value),"null"]}}return schema};var defaultControl=(schema)=>{if(schema.$ref!==undefined||(schema.anyOf!==undefined||schema.oneOf!==undefined)&&schema.type===undefined){return"custom"}if(Array.isArray(schema.enum)){return"select"}const types=scalarTypes(schema);if(types.includes("boolean")){return"checkbox"}if(types.includes("number")||types.includes("integer")){return"number"}if(schema.format==="email"){return"email"}if(schema.format==="date"){return"date"}if(schema.format==="date-time"){return"datetime-local"}return types.some((type)=>type==="object"||type==="array")?"custom":"text"};var configuredControl=(config,schema)=>{switch(config.control){case"text":case"email":case"number":case"checkbox":case"date":case"datetime-local":case"select":case"custom":{return config.control}case undefined:{return defaultControl(schema)}default:{return"custom"}}};var formFields=(entity,mode)=>{const properties=schemaProperties(entity,mode);const entityProperties=schemaProperties(entity);const required=requiredFields(entity,mode);return entity.config.forms[mode].fields.map((name)=>{const config=entity.config.fields[name];if(config===undefined){throw new Error(`Missing entity field configuration: ${name}`)}const candidate=properties[name]??entityProperties[name];const schema=isObject2(candidate)?presentationSchema(candidate):{};const entityField=entityProperties[name];const enums=Array.isArray(schema.enum)?schema.enum.filter((value)=>typeof value==="string"||typeof value==="number"||typeof value==="boolean"):[];return{control:configuredControl(config,schema),label:config.label,name,nullable:scalarTypes(schema).includes("null")||Array.isArray(schema.enum)&&schema.enum.includes(null),options:enums.map((value)=>({label:String(value),value})),readOnly:config.readOnly===true||schema.readOnly===true||isObject2(entityField)&&entityField.readOnly===true,required:required.has(name)}})};var displayValue=(value)=>{if(value===null||value===undefined){return"—"}if(typeof value==="boolean"){return value?"Yes":"No"}return typeof value==="object"?JSON.stringify(value):String(value)};var renderField=(entity,record,name,renderers)=>{const renderer=entity.config.fields[name]?.renderer;return renderer===undefined||renderers?.[renderer]===undefined?displayValue(record.value[name]):renderers[renderer]({field:name,record})};var sortFor=(state,field)=>{const[current]=state.state.sort;return[{direction:current?.field===field&&current.direction==="asc"?"desc":"asc",field}]};var QueryControls=({view})=>jsx2(ResourceFiltersBar,{controls:[{control:jsx2(ResourceFilterPrimitive,{label:"Search",onChange:(value)=>view.setTextSearch(value),value:view.state.textSearch}),fullWidth:true,key:"search"}]});var EntityStatus=({state})=>{if(state.authState.status!=="authenticated"){return jsx2("output",{children:state.authState.status})}if(state.loading){return jsx2("output",{children:"Loading"})}if(state.error!==null){return jsx2("output",{role:"alert",children:state.error.message})}return null};var EntityPagination=({result,view,pending})=>{if(result===undefined||result.pagination!=="page"){return null}return jsx2(ResourcePaginationPrimitive,{currentPage:result.page,totalPages:result.totalPages,hasPreviousPage:result.page>1,hasNextPage:result.page<result.totalPages,isPending:pending,onPageChange:(page)=>view.setPage(page),onPrevious:()=>view.setPage(result.page-1),onNext:()=>view.setPage(result.page+1)})};var ControlledEntityTable=({entity,empty,renderers,variant,view})=>{const result=useEntityList2(entity.contract,view.query);const names=variant===undefined?entity.config.table.columns:entity.config.table.variants?.[variant]?.columns??entity.config.table.columns;const columns=names.map((name)=>({id:name,label:entity.config.fields[name]?.label??name}));const hasStatus=result.authState.status!=="authenticated"||result.loading||result.error!==null;return jsxs("section",{children:[jsx2(QueryControls,{view}),hasStatus?jsx2(EntityStatus,{state:result}):jsxs(Fragment,{children:[jsx2(ResourceTablePrimitive,{columns:columns.map((column)=>({...column,label:entity.contract.query.sortableFields.includes(column.id)?jsx2("button",{type:"button",onClick:()=>view.setSort(sortFor(view,column.id)),children:column.label}):column.label})),empty,getRowKey:(record)=>record.id,renderCell:(record,column)=>{const name=names.find((field)=>field===column.id);return name===undefined?null:renderField(entity,record,name,renderers)},rows:result.data?.items??[]}),jsx2(EntityPagination,{pending:result.refreshing,result:result.data,view})]})]})};var UrlEntityTable=(props)=>jsx2(ControlledEntityTable,{...props,view:useEntityViewState2(props.namespace,{contract:props.entity.contract,pageSize:props.pageSize??25})});var MemoryEntityTable=(props)=>jsx2(ControlledEntityTable,{...props,view:useMemoryEntityViewState2(props.pageSize===undefined?{}:{pageSize:props.pageSize})});var EntityTable2=(props)=>props.viewState==="memory"?jsx2(MemoryEntityTable,{...props}):jsx2(UrlEntityTable,{...props,namespace:props.namespace});var ControlledEntityList=({entity,empty,renderers,view})=>{const result=useEntityList2(entity.contract,view.query);const hasStatus=result.authState.status!=="authenticated"||result.loading||result.error!==null;return jsxs("section",{children:[jsx2(QueryControls,{view}),hasStatus?jsx2(EntityStatus,{state:result}):jsxs(Fragment,{children:[jsx2(ResourceListPrimitive,{empty,getItemKey:(record)=>record.id,items:result.data?.items??[],renderItem:(record)=>jsxs("article",{children:[jsx2("strong",{children:renderField(entity,record,entity.config.list.title,renderers)}),entity.config.list.description===undefined?null:jsx2("p",{children:renderField(entity,record,entity.config.list.description,renderers)})]})}),jsx2(EntityPagination,{pending:result.refreshing,result:result.data,view})]})]})};var UrlEntityList=(props)=>jsx2(ControlledEntityList,{...props,view:useEntityViewState2(props.namespace,{contract:props.entity.contract,pageSize:props.pageSize??25})});var MemoryEntityList=(props)=>jsx2(ControlledEntityList,{...props,view:useMemoryEntityViewState2(props.pageSize===undefined?{}:{pageSize:props.pageSize})});var EntityList2=(props)=>props.viewState==="memory"?jsx2(MemoryEntityList,{...props}):jsx2(UrlEntityList,{...props,namespace:props.namespace});var initialFormValues=(entity,mode,supplied,record)=>{const values={};const properties=schemaProperties(entity,mode);const required=requiredFields(entity,mode);for(const name of entity.config.forms[mode].fields){const schema=properties[name];if(required.has(name)&&isObject2(schema)&&scalarTypes(presentationSchema(schema)).includes("boolean")){values[name]=false}if(isObject2(schema)&&schema.default!==undefined){values[name]=schema.default}if(record?.value[name]!==undefined){values[name]=record.value[name]}if(supplied?.[name]!==undefined){values[name]=supplied[name]}}return values};var controlRenderer=(entity,controls)=>function renderEntityControl(props){const fields=entity.config.fields;const key=fields[props.field.name]?.control;return key===undefined||controls?.[key]===undefined?jsxs("p",{role:"alert",children:["A custom control is required for ",props.field.label,"."]}):controls[key](props)};var mutationMessage=(mutation)=>{if(mutation.status==="conflict"){return"This entity changed. Your draft is preserved."}if(mutation.status==="uncertain"){return"The write outcome is unknown. Resubmit the same action to resolve it."}return mutation.error?.resourceError.message};var writableValues=(fields,values)=>{const writable=new Set(fields.filter((field)=>!field.readOnly).map((field)=>field.name));return Object.fromEntries(Object.entries(values).filter(([name])=>writable.has(name)))};var displayedValues=(fields,values)=>Object.fromEntries(Object.entries(values).map(([name,value])=>{if(typeof value!=="string"||fields.find((field)=>field.name===name)?.control!=="datetime-local"){return[name,value]}const date=new Date(value);if(Number.isNaN(date.getTime())){return[name,value]}return[name,new Date(date.getTime()-date.getTimezoneOffset()*60000).toISOString().slice(0,23)]}));var wireValue=(fields,name,value)=>{if(typeof value!=="string"||value===""||fields.find((field)=>field.name===name)?.control!=="datetime-local"){return value}const date=new Date(value);return Number.isNaN(date.getTime())?value:date.toISOString()};var CreateEntityForm=(props)=>{const mutation=useEntityCreate2(props.entity.contract);const[values,setValues]=useState2(()=>initialFormValues(props.entity,"create",props.initialValues));const fields=useMemo5(()=>formFields(props.entity,"create"),[props.entity]);return jsx2(ResourceFormPrimitive,{label:"Create entity",fields,values:displayedValues(fields,values),disabled:!mutation.available,pending:mutation.pending,error:mutationMessage(mutation),...props.onCancel===undefined?{}:{onCancel:props.onCancel},onChange:(name,value)=>setValues((current)=>({...current,[name]:wireValue(fields,name,value)})),onSubmit:async()=>{const value=writableValues(fields,values);const action=mutation.status==="uncertain"?mutation.resubmit():mutation.submit({value});const result=await action;if(result.ok){props.onSuccess?.(result.value)}},renderControl:controlRenderer(props.entity,props.controls),submitLabel:mutation.status==="uncertain"?"Resubmit":"Create"})};var UpdateEntityForm=(props)=>{const mutation=useEntityUpdate2(props.entity.contract,{id:props.record.id});const[draft,setDraft]=useState2(()=>({expectedRevision:props.record.revision,values:initialFormValues(props.entity,"update",props.initialValues,props.record)}));const{expectedRevision,values}=draft;const fields=useMemo5(()=>formFields(props.entity,"update"),[props.entity]);return jsx2(ResourceFormPrimitive,{label:"Update entity",fields,values:displayedValues(fields,values),disabled:!mutation.available,pending:mutation.pending,error:mutationMessage(mutation),...props.onCancel===undefined?{}:{onCancel:props.onCancel},onChange:(name,value)=>setDraft((current)=>({...current,values:{...current.values,[name]:wireValue(fields,name,value)}})),onSubmit:async()=>{const value=writableValues(fields,values);const result=await(mutation.status==="uncertain"?mutation.resubmit():mutation.submit({expectedRevision,value}));if(result.ok){props.onSuccess?.(result.value)}},renderControl:controlRenderer(props.entity,props.controls),submitLabel:mutation.status==="uncertain"?"Resubmit":"Save"})};var EntityForm2=(props)=>{const runtime=useEntityRuntime();if(runtime.state.status!=="authenticated"){return jsx2("output",{children:runtime.state.status})}return props.mode==="create"?jsx2(CreateEntityForm,{...props},runtime.formScope):jsx2(UpdateEntityForm,{...props,record:props.record},JSON.stringify([runtime.formScope,props.record.id]))};
2
+ export{resourceKeys,ResourceQueryError2,unwrapResourceResult2,createResourceListQueryOptions,mapResourceAuthState2,hasResourceCapability2,clearProtectedResourceQueries,EntityRuntimeProvider,createDelegatedEntitySource2,defineEntity2,useEntityUpdate2,useEntityCreate2,useEntityDelete2,useEntityList2,useEntityRecord2,useEntityViewState2,useMemoryEntityViewState2,EntityTable2,EntityList2,EntityForm2};
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{EntityRuntimeProvider,createDelegatedEntitySource,defineEntity2,useEntityViewState2,useMemoryEntityViewState2,EntityTable2,EntityList2,EntityForm2}from"./index-wb56c1cj.js";import{__export}from"./index-6ra894v2.js";var exports_src={};__export(exports_src,{AgentPrompt:()=>AgentPrompt,AgentPromptPrimitive:()=>AgentPromptPrimitive,CollectiveIntelligenceLoginProvider:()=>CollectiveIntelligenceLoginProvider,CollectiveIntelligenceProvider:()=>CollectiveIntelligenceProvider,EntityForm:()=>EntityForm2,EntityList:()=>EntityList2,EntityTable:()=>EntityTable2,LoginButton:()=>LoginButton,LoginCallback:()=>LoginCallback,LoginCallbackPrimitive:()=>LoginCallbackPrimitive,RealtimeProvider:()=>RealtimeProvider,SessionGate:()=>SessionGate,clientSdkReactEntrypoint:()=>clientSdkReactEntrypoint,createDelegatedEntitySource:()=>createDelegatedEntitySource,createPromptKeyHandler:()=>createPromptKeyHandler,defineEntity:()=>defineEntity2,useAgentInvocation:()=>useAgentInvocation,useAgents:()=>useAgents,useAttachments:()=>useAttachments,useClientContext:()=>useClientContext,useCollectiveIntelligenceAuth:()=>useCollectiveIntelligenceAuth,useCollectiveIntelligenceClient:()=>useCollectiveIntelligenceClient,useEntityViewState:()=>useEntityViewState2,useKnowledge:()=>useKnowledge,useMemoryEntityViewState:()=>useMemoryEntityViewState2,useOrganizationClient:()=>useOrganizationClient,useRealtimeClient:()=>useRealtimeClient,useRealtimeTopic:()=>useRealtimeTopic,useRuns:()=>useRuns,useSession:()=>useSession,useSkills:()=>useSkills,useWorkflows:()=>useWorkflows});import{useCallback,useId,useState as useState2}from"react";import{QueryClient,QueryClientProvider}from"@tanstack/react-query";import{createContext,useContext,useMemo,useState}from"react";import{jsx}from"react/jsx-runtime";var ClientContext=createContext(null);var CollectiveIntelligenceProvider=(props)=>{const{clientFactory}=props;const[ownedQueryClient]=useState(()=>new QueryClient({defaultOptions:{mutations:{retry:false},queries:{retry:false}}}));const ownedClient=useMemo(()=>clientFactory===undefined?undefined:clientFactory(),[clientFactory]);const client=props.client??ownedClient;const queryClient=props.queryClient??ownedQueryClient;if(client===undefined){throw new TypeError("A client or clientFactory is required")}return jsx(ClientContext.Provider,{value:client,children:jsx(QueryClientProvider,{client:queryClient,children:props.entitySource===undefined?props.children:jsx(EntityRuntimeProvider,{onWriteFailed:props.onWriteFailed,source:props.entitySource,children:props.children})})})};var useCollectiveIntelligenceClient=()=>{const client=useContext(ClientContext);if(client===null){throw new Error("CollectiveIntelligenceProvider must wrap Collective Intelligence hooks")}return client};var useOrganizationClient=(organizationId)=>{const client=useCollectiveIntelligenceClient();return useMemo(()=>client.forOrganization(organizationId),[client,organizationId])};var useKnowledge=(organizationId)=>useOrganizationClient(organizationId).knowledge;var useAgents=(organizationId)=>useOrganizationClient(organizationId).agents;var useSkills=(organizationId)=>useOrganizationClient(organizationId).skills;var useWorkflows=(organizationId)=>useOrganizationClient(organizationId).workflows;var useRuns=(organizationId)=>useOrganizationClient(organizationId).runs;var useAttachments=(organizationId)=>useOrganizationClient(organizationId).attachments;var useClientContext=(organizationId)=>useOrganizationClient(organizationId).context;import{jsx as jsx2,jsxs}from"react/jsx-runtime";var ignoreSubmit=()=>false;var createPromptKeyHandler=(onSubmit)=>(event)=>{if(event.key==="Enter"&&!event.shiftKey&&!event.isComposing){event.preventDefault();onSubmit()}};var AgentPromptPrimitive=({autoFocus=false,className,components,id,label,onChange,onSubmit,pending,status,style,submitLabel="Send",value})=>{const Form=components?.Form??"form";const Label=components?.Label??"label";const Textarea=components?.Textarea??"textarea";const Button=components?.Button??"button";const Status=components?.Status??"div";const statusId=`${id}-status`;const submit=(event)=>{event.preventDefault();if(!pending){onSubmit()}};const onKeyDown=(event)=>{createPromptKeyHandler(pending?ignoreSubmit:onSubmit)({isComposing:event.nativeEvent.isComposing,key:event.key,preventDefault:()=>{event.preventDefault()},shiftKey:event.shiftKey})};return jsxs(Form,{className:["ci-agent-prompt",className].filter(Boolean).join(" "),onSubmit:submit,style,children:[jsx2(Label,{className:"ci-agent-prompt__label",htmlFor:id,children:label}),jsx2(Textarea,{"aria-describedby":statusId,autoFocus,className:"ci-agent-prompt__input",disabled:pending,id,onChange:(event)=>{onChange(event.currentTarget.value)},onKeyDown,value}),jsx2(Button,{className:"ci-agent-prompt__submit",disabled:pending||value.trim().length===0,type:"submit",children:submitLabel}),jsx2(Status,{"aria-live":"polite",className:"ci-agent-prompt__status",id:statusId,children:status})]})};var useAgentInvocation=(organizationId)=>{const{agents}=useOrganizationClient(organizationId);const[state,setState]=useState2({status:"idle"});const invoke=useCallback(async(input)=>{setState({status:"submitting"});try{const result=await agents.invoke(input);setState(result.ok?{result,status:"success"}:{result,status:"failure"});return result}catch(error){setState({error,status:"error"});throw error}},[agents]);return{invoke,reset:()=>{setState({status:"idle"})},state}};var invocationStatus=(state)=>{switch(state.status){case"submitting":{return"Sending"}case"success":{return"Request started"}case"failure":{return state.result.error.message}case"error":{return"Request failed"}case"idle":{return null}default:{return null}}};var EMPTY_AGENT_PROMPT_COMPONENTS={};var EMPTY_AGENT_PROMPT_STYLE={};var createDefaultIdempotencyKey=()=>globalThis.crypto.randomUUID();var AgentPrompt=({agentId,autoFocus=false,className="",components=EMPTY_AGENT_PROMPT_COMPONENTS,createIdempotencyKey=createDefaultIdempotencyKey,label="Message",onResult,organizationId,style=EMPTY_AGENT_PROMPT_STYLE,submitLabel="Send"})=>{const id=`ci-agent-prompt-${useId().replaceAll(":","")}`;const[value,setValue]=useState2("");const invocation=useAgentInvocation(organizationId);const submit=()=>{const prompt=value.trim();if(prompt.length===0||invocation.state.status==="submitting"){return}const submitInvocation=async()=>{try{const result=await invocation.invoke({agentId,idempotencyKey:createIdempotencyKey(),input:{prompt}});if(result.ok){setValue("")}onResult?.(result)}catch{}};submitInvocation()};return jsx2(AgentPromptPrimitive,{autoFocus,className,components,id,label,onChange:setValue,onSubmit:submit,pending:invocation.state.status==="submitting",status:invocationStatus(invocation.state),style,submitLabel,value})};import{FederatedAuthError}from"@collective-intelligence/external-apps-client-sdk";import{createContext as createContext2,useCallback as useCallback2,useContext as useContext2,useEffect,useMemo as useMemo2,useSyncExternalStore}from"react";import{jsx as jsx3}from"react/jsx-runtime";var AuthContext=createContext2(null);var toFederatedAuthError=(error)=>new FederatedAuthError("authorization_failed",error.message);var unknownAuthError=()=>new FederatedAuthError("authorization_failed","Sign in failed");var CollectiveIntelligenceLoginProvider=(props)=>{const state=useSyncExternalStore(props.auth.subscribe,props.auth.getState,props.auth.getState);const contextValue=useMemo2(()=>({auth:props.auth,state}),[props.auth,state]);return jsx3(AuthContext.Provider,{value:contextValue,children:props.clientFactory===undefined?jsx3(CollectiveIntelligenceProvider,{client:props.client,entitySource:props.entitySource,onWriteFailed:props.onWriteFailed,queryClient:props.queryClient,children:props.children}):jsx3(CollectiveIntelligenceProvider,{clientFactory:props.clientFactory,entitySource:props.entitySource,onWriteFailed:props.onWriteFailed,queryClient:props.queryClient,children:props.children})})};var useCollectiveIntelligenceAuth=()=>{const value=useContext2(AuthContext);if(value===null){throw new Error("CollectiveIntelligenceLoginProvider must wrap authentication bindings")}return{...value,beginLogin:value.auth.beginLogin,completeLogin:value.auth.completeLogin,logout:value.auth.logout,reauthorize:value.auth.reauthorize}};var LoginButton=({children="Sign in with Collective Intelligence",className,components,disabled=false,onError,returnTo,style})=>{const{auth,state}=useCollectiveIntelligenceAuth();const Button=components?.Button??"button";const redirecting=state.status==="redirecting";const onClick=useCallback2((event)=>{event.preventDefault();const target=returnTo??globalThis.location.href;const begin=async()=>{try{await auth.beginLogin({returnTo:target})}catch(error){onError?.(error instanceof Error?toFederatedAuthError(error):unknownAuthError())}};begin()},[auth,onError,returnTo]);return jsx3(Button,{"aria-busy":redirecting,className:["ci-login-button",className].filter(Boolean).join(" "),disabled:disabled||redirecting,onClick,style,type:"button",children})};var callbackMessage=(state)=>{switch(state.status){case"authenticated":{return"Sign in complete"}case"error":{return state.error.message}case"expired":{return"Sign in expired"}case"anonymous":case"redirecting":{return"Completing sign in"}default:{return"Completing sign in"}}};var LoginCallbackPrimitive=({className,components,state,style})=>{const Status=components?.Status??"div";return jsx3(Status,{"aria-live":"polite",className:["ci-login-callback",className].filter(Boolean).join(" "),style,children:callbackMessage(state)})};var LoginCallback=({callbackUrl,onComplete,onError,...primitiveProps})=>{const{auth,state}=useCollectiveIntelligenceAuth();useEffect(()=>{const url=callbackUrl??globalThis.location.href;const complete=async()=>{try{const{returnTo}=await auth.completeLogin(url);onComplete?.(returnTo)}catch(error){onError?.(error instanceof Error?toFederatedAuthError(error):unknownAuthError())}};complete()},[auth,callbackUrl,onComplete,onError]);return jsx3(LoginCallbackPrimitive,{...primitiveProps,state})};var useSession=()=>{const{state}=useCollectiveIntelligenceAuth();return state};var SessionGate=({children,fallback=null})=>{const session=useSession();if(session.status!=="authenticated"){return fallback}return children};import{createRealtimeClient}from"@collective-intelligence/external-apps-client-sdk";import{createContext as createContext3,useContext as useContext3,useEffect as useEffect2,useState as useState3}from"react";import{jsx as jsx4}from"react/jsx-runtime";var idle={connections:0,lastEventId:undefined,status:"idle",topics:[]};var hasOnReset=(options)=>options.onReset!==undefined;var shareClient=(initial)=>{let options=initial;let client;let holders=0;const subscriptions=new Set;const create=()=>createRealtimeClient({document:globalThis.document,window:globalThis.window,...options,onAccessChanged:()=>options.onAccessChanged?.(),...hasOnReset(options)&&{onReset:()=>options.onReset?.()}});const acquire=()=>{holders+=1;client??=create();return client};const release=()=>{holders-=1;queueMicrotask(()=>{if(holders===0){client?.close();client=undefined}})};const subscribe=(topic,onChanges)=>{const subscription={onChanges,topic,unsubscribe:acquire().subscribe(topic,onChanges)};subscriptions.add(subscription);return()=>{if(subscriptions.delete(subscription)){subscription.unsubscribe();release()}}};return{acquire,getState:()=>client?.getState()??idle,release,subscribe,update:(next)=>{const previous=options;options=next;if(client===undefined||hasOnReset(next)===hasOnReset(previous)){return}for(const subscription of subscriptions){subscription.unsubscribe()}client.close();client=create();for(const subscription of subscriptions){subscription.unsubscribe=client.subscribe(subscription.topic,subscription.onChanges)}}}};var RealtimeContext=createContext3(null);var RealtimeProvider=({children,...options})=>{const[shared]=useState3(()=>shareClient(options));useEffect2(()=>{shared.update(options)});useEffect2(()=>{shared.acquire();return shared.release},[shared]);return jsx4(RealtimeContext.Provider,{value:shared,children})};var useRealtimeClient=()=>{const client=useContext3(RealtimeContext);if(client===null){throw new Error("useRealtimeClient requires a RealtimeProvider")}return client};import{realtimeTopicKey}from"@collective-intelligence/external-apps-client-sdk";import{useEffect as useEffect3,useRef,useState as useState4}from"react";var useRealtimeTopic=(topic,onChanges)=>{const client=useRealtimeClient();const latest=useRef(onChanges);const key=topic===null?null:realtimeTopicKey(topic);const[subscribed,setSubscribed]=useState4({key,topic});if(subscribed.key!==key){setSubscribed({key,topic})}useEffect3(()=>{latest.current=onChanges});useEffect3(()=>subscribed.topic===null?undefined:client.subscribe(subscribed.topic,(changes)=>latest.current(changes)),[client,subscribed])};"use client";var clientSdkReactEntrypoint="react";"use client";var{AgentPrompt:AgentPrompt2,AgentPromptPrimitive:AgentPromptPrimitive2,CollectiveIntelligenceLoginProvider:CollectiveIntelligenceLoginProvider2,CollectiveIntelligenceProvider:CollectiveIntelligenceProvider2,LoginButton:LoginButton2,LoginCallback:LoginCallback2,LoginCallbackPrimitive:LoginCallbackPrimitive2,RealtimeProvider:RealtimeProvider2,SessionGate:SessionGate2,clientSdkReactEntrypoint:clientSdkReactEntrypoint2,createPromptKeyHandler:createPromptKeyHandler2,useAgents:useAgents2,useAttachments:useAttachments2,useClientContext:useClientContext2,useCollectiveIntelligenceAuth:useCollectiveIntelligenceAuth2,useCollectiveIntelligenceClient:useCollectiveIntelligenceClient2,useKnowledge:useKnowledge2,useOrganizationClient:useOrganizationClient2,useRealtimeClient:useRealtimeClient2,useRealtimeTopic:useRealtimeTopic2,useRuns:useRuns2,useSession:useSession2,useSkills:useSkills2,useWorkflows:useWorkflows2,useAgentInvocation:useAgentInvocation2}=exports_src;export{AgentPrompt2 as AgentPrompt,AgentPromptPrimitive2 as AgentPromptPrimitive,CollectiveIntelligenceLoginProvider2 as CollectiveIntelligenceLoginProvider,CollectiveIntelligenceProvider2 as CollectiveIntelligenceProvider,LoginButton2 as LoginButton,LoginCallback2 as LoginCallback,LoginCallbackPrimitive2 as LoginCallbackPrimitive,RealtimeProvider2 as RealtimeProvider,SessionGate2 as SessionGate,clientSdkReactEntrypoint2 as clientSdkReactEntrypoint,createPromptKeyHandler2 as createPromptKeyHandler,useAgentInvocation2 as useAgentInvocation,useAgents2 as useAgents,useAttachments2 as useAttachments,useClientContext2 as useClientContext,useCollectiveIntelligenceAuth2 as useCollectiveIntelligenceAuth,useCollectiveIntelligenceClient2 as useCollectiveIntelligenceClient,useKnowledge2 as useKnowledge,useOrganizationClient2 as useOrganizationClient,useRealtimeClient2 as useRealtimeClient,useRealtimeTopic2 as useRealtimeTopic,useRuns2 as useRuns,useSession2 as useSession,useSkills2 as useSkills,useWorkflows2 as useWorkflows};
2
+ import{EntityRuntimeProvider,createDelegatedEntitySource2,defineEntity2,useEntityViewState2,useMemoryEntityViewState2,EntityTable2,EntityList2,EntityForm2}from"./index-qb0zr9z9.js";import{__export}from"./index-6ra894v2.js";var exports_src={};__export(exports_src,{AgentPrompt:()=>AgentPrompt,AgentPromptPrimitive:()=>AgentPromptPrimitive,CollectiveIntelligenceLoginProvider:()=>CollectiveIntelligenceLoginProvider,CollectiveIntelligenceProvider:()=>CollectiveIntelligenceProvider,EntityForm:()=>EntityForm2,EntityList:()=>EntityList2,EntityTable:()=>EntityTable2,LoginButton:()=>LoginButton,LoginCallback:()=>LoginCallback,LoginCallbackPrimitive:()=>LoginCallbackPrimitive,RealtimeProvider:()=>RealtimeProvider,SessionGate:()=>SessionGate,clientSdkReactEntrypoint:()=>clientSdkReactEntrypoint,createDelegatedEntitySource:()=>createDelegatedEntitySource2,createPromptKeyHandler:()=>createPromptKeyHandler,defineEntity:()=>defineEntity2,useAgentInvocation:()=>useAgentInvocation,useAgents:()=>useAgents,useAttachments:()=>useAttachments,useClientContext:()=>useClientContext,useCollectiveIntelligenceAuth:()=>useCollectiveIntelligenceAuth,useCollectiveIntelligenceClient:()=>useCollectiveIntelligenceClient,useEntityViewState:()=>useEntityViewState2,useKnowledge:()=>useKnowledge,useMemoryEntityViewState:()=>useMemoryEntityViewState2,useOrganizationClient:()=>useOrganizationClient,useRealtimeClient:()=>useRealtimeClient,useRealtimeTopic:()=>useRealtimeTopic,useRuns:()=>useRuns,useSession:()=>useSession,useSkills:()=>useSkills,useWorkflows:()=>useWorkflows});import{useCallback,useId,useState as useState2}from"react";import{QueryClient,QueryClientProvider}from"@tanstack/react-query";import{createContext,useContext,useMemo,useState}from"react";import{jsx}from"react/jsx-runtime";var ClientContext=createContext(null);var CollectiveIntelligenceProvider=(props)=>{const{clientFactory}=props;const[ownedQueryClient]=useState(()=>new QueryClient({defaultOptions:{mutations:{retry:false},queries:{retry:false}}}));const ownedClient=useMemo(()=>clientFactory===undefined?undefined:clientFactory(),[clientFactory]);const client=props.client??ownedClient;const queryClient=props.queryClient??ownedQueryClient;if(client===undefined){throw new TypeError("A client or clientFactory is required")}return jsx(ClientContext.Provider,{value:client,children:jsx(QueryClientProvider,{client:queryClient,children:props.entitySource===undefined?props.children:jsx(EntityRuntimeProvider,{onWriteFailed:props.onWriteFailed,source:props.entitySource,children:props.children})})})};var useCollectiveIntelligenceClient=()=>{const client=useContext(ClientContext);if(client===null){throw new Error("CollectiveIntelligenceProvider must wrap Collective Intelligence hooks")}return client};var useOrganizationClient=(organizationId)=>{const client=useCollectiveIntelligenceClient();return useMemo(()=>client.forOrganization(organizationId),[client,organizationId])};var useKnowledge=(organizationId)=>useOrganizationClient(organizationId).knowledge;var useAgents=(organizationId)=>useOrganizationClient(organizationId).agents;var useSkills=(organizationId)=>useOrganizationClient(organizationId).skills;var useWorkflows=(organizationId)=>useOrganizationClient(organizationId).workflows;var useRuns=(organizationId)=>useOrganizationClient(organizationId).runs;var useAttachments=(organizationId)=>useOrganizationClient(organizationId).attachments;var useClientContext=(organizationId)=>useOrganizationClient(organizationId).context;import{jsx as jsx2,jsxs}from"react/jsx-runtime";var ignoreSubmit=()=>false;var createPromptKeyHandler=(onSubmit)=>(event)=>{if(event.key==="Enter"&&!event.shiftKey&&!event.isComposing){event.preventDefault();onSubmit()}};var AgentPromptPrimitive=({autoFocus=false,className,components,id,label,onChange,onSubmit,pending,status,style,submitLabel="Send",value})=>{const Form=components?.Form??"form";const Label=components?.Label??"label";const Textarea=components?.Textarea??"textarea";const Button=components?.Button??"button";const Status=components?.Status??"div";const statusId=`${id}-status`;const submit=(event)=>{event.preventDefault();if(!pending){onSubmit()}};const onKeyDown=(event)=>{createPromptKeyHandler(pending?ignoreSubmit:onSubmit)({isComposing:event.nativeEvent.isComposing,key:event.key,preventDefault:()=>{event.preventDefault()},shiftKey:event.shiftKey})};return jsxs(Form,{className:["ci-agent-prompt",className].filter(Boolean).join(" "),onSubmit:submit,style,children:[jsx2(Label,{className:"ci-agent-prompt__label",htmlFor:id,children:label}),jsx2(Textarea,{"aria-describedby":statusId,autoFocus,className:"ci-agent-prompt__input",disabled:pending,id,onChange:(event)=>{onChange(event.currentTarget.value)},onKeyDown,value}),jsx2(Button,{className:"ci-agent-prompt__submit",disabled:pending||value.trim().length===0,type:"submit",children:submitLabel}),jsx2(Status,{"aria-live":"polite",className:"ci-agent-prompt__status",id:statusId,children:status})]})};var useAgentInvocation=(organizationId)=>{const{agents}=useOrganizationClient(organizationId);const[state,setState]=useState2({status:"idle"});const invoke=useCallback(async(input)=>{setState({status:"submitting"});try{const result=await agents.invoke(input);setState(result.ok?{result,status:"success"}:{result,status:"failure"});return result}catch(error){setState({error,status:"error"});throw error}},[agents]);return{invoke,reset:()=>{setState({status:"idle"})},state}};var invocationStatus=(state)=>{switch(state.status){case"submitting":{return"Sending"}case"success":{return"Request started"}case"failure":{return state.result.error.message}case"error":{return"Request failed"}case"idle":{return null}default:{return null}}};var EMPTY_AGENT_PROMPT_COMPONENTS={};var EMPTY_AGENT_PROMPT_STYLE={};var createDefaultIdempotencyKey=()=>globalThis.crypto.randomUUID();var AgentPrompt=({agentId,autoFocus=false,className="",components=EMPTY_AGENT_PROMPT_COMPONENTS,createIdempotencyKey=createDefaultIdempotencyKey,label="Message",onResult,organizationId,style=EMPTY_AGENT_PROMPT_STYLE,submitLabel="Send"})=>{const id=`ci-agent-prompt-${useId().replaceAll(":","")}`;const[value,setValue]=useState2("");const invocation=useAgentInvocation(organizationId);const submit=()=>{const prompt=value.trim();if(prompt.length===0||invocation.state.status==="submitting"){return}const submitInvocation=async()=>{try{const result=await invocation.invoke({agentId,idempotencyKey:createIdempotencyKey(),input:{prompt}});if(result.ok){setValue("")}onResult?.(result)}catch{}};submitInvocation()};return jsx2(AgentPromptPrimitive,{autoFocus,className,components,id,label,onChange:setValue,onSubmit:submit,pending:invocation.state.status==="submitting",status:invocationStatus(invocation.state),style,submitLabel,value})};import{FederatedAuthError}from"@collective-intelligence/external-apps-client-sdk";import{createContext as createContext2,useCallback as useCallback2,useContext as useContext2,useEffect,useMemo as useMemo2,useSyncExternalStore}from"react";import{jsx as jsx3}from"react/jsx-runtime";var AuthContext=createContext2(null);var toFederatedAuthError=(error)=>new FederatedAuthError("authorization_failed",error.message);var unknownAuthError=()=>new FederatedAuthError("authorization_failed","Sign in failed");var CollectiveIntelligenceLoginProvider=(props)=>{const state=useSyncExternalStore(props.auth.subscribe,props.auth.getState,props.auth.getState);const contextValue=useMemo2(()=>({auth:props.auth,state}),[props.auth,state]);return jsx3(AuthContext.Provider,{value:contextValue,children:props.clientFactory===undefined?jsx3(CollectiveIntelligenceProvider,{client:props.client,entitySource:props.entitySource,onWriteFailed:props.onWriteFailed,queryClient:props.queryClient,children:props.children}):jsx3(CollectiveIntelligenceProvider,{clientFactory:props.clientFactory,entitySource:props.entitySource,onWriteFailed:props.onWriteFailed,queryClient:props.queryClient,children:props.children})})};var useCollectiveIntelligenceAuth=()=>{const value=useContext2(AuthContext);if(value===null){throw new Error("CollectiveIntelligenceLoginProvider must wrap authentication bindings")}return{...value,beginLogin:value.auth.beginLogin,completeLogin:value.auth.completeLogin,logout:value.auth.logout,reauthorize:value.auth.reauthorize}};var LoginButton=({children="Sign in with Collective Intelligence",className,components,disabled=false,onError,returnTo,style})=>{const{auth,state}=useCollectiveIntelligenceAuth();const Button=components?.Button??"button";const redirecting=state.status==="redirecting";const onClick=useCallback2((event)=>{event.preventDefault();const target=returnTo??globalThis.location.href;const begin=async()=>{try{await auth.beginLogin({returnTo:target})}catch(error){onError?.(error instanceof Error?toFederatedAuthError(error):unknownAuthError())}};begin()},[auth,onError,returnTo]);return jsx3(Button,{"aria-busy":redirecting,className:["ci-login-button",className].filter(Boolean).join(" "),disabled:disabled||redirecting,onClick,style,type:"button",children})};var callbackMessage=(state)=>{switch(state.status){case"authenticated":{return"Sign in complete"}case"error":{return state.error.message}case"expired":{return"Sign in expired"}case"anonymous":case"redirecting":{return"Completing sign in"}default:{return"Completing sign in"}}};var LoginCallbackPrimitive=({className,components,state,style})=>{const Status=components?.Status??"div";return jsx3(Status,{"aria-live":"polite",className:["ci-login-callback",className].filter(Boolean).join(" "),style,children:callbackMessage(state)})};var LoginCallback=({callbackUrl,onComplete,onError,...primitiveProps})=>{const{auth,state}=useCollectiveIntelligenceAuth();useEffect(()=>{const url=callbackUrl??globalThis.location.href;const complete=async()=>{try{const{returnTo}=await auth.completeLogin(url);onComplete?.(returnTo)}catch(error){onError?.(error instanceof Error?toFederatedAuthError(error):unknownAuthError())}};complete()},[auth,callbackUrl,onComplete,onError]);return jsx3(LoginCallbackPrimitive,{...primitiveProps,state})};var useSession=()=>{const{state}=useCollectiveIntelligenceAuth();return state};var SessionGate=({children,fallback=null})=>{const session=useSession();if(session.status!=="authenticated"){return fallback}return children};import{createRealtimeClient}from"@collective-intelligence/external-apps-client-sdk";import{createContext as createContext3,useContext as useContext3,useEffect as useEffect2,useState as useState3}from"react";import{jsx as jsx4}from"react/jsx-runtime";var idle={connections:0,lastEventId:undefined,status:"idle",topics:[]};var hasOnReset=(options)=>options.onReset!==undefined;var shareClient=(initial)=>{let options=initial;let client;let holders=0;const subscriptions=new Set;const create=()=>createRealtimeClient({document:globalThis.document,window:globalThis.window,...options,onAccessChanged:()=>options.onAccessChanged?.(),...hasOnReset(options)&&{onReset:()=>options.onReset?.()}});const acquire=()=>{holders+=1;client??=create();return client};const release=()=>{holders-=1;queueMicrotask(()=>{if(holders===0){client?.close();client=undefined}})};const subscribe=(topic,onChanges)=>{const subscription={onChanges,topic,unsubscribe:acquire().subscribe(topic,onChanges)};subscriptions.add(subscription);return()=>{if(subscriptions.delete(subscription)){subscription.unsubscribe();release()}}};return{acquire,getState:()=>client?.getState()??idle,release,subscribe,update:(next)=>{const previous=options;options=next;if(client===undefined||hasOnReset(next)===hasOnReset(previous)){return}for(const subscription of subscriptions){subscription.unsubscribe()}client.close();client=create();for(const subscription of subscriptions){subscription.unsubscribe=client.subscribe(subscription.topic,subscription.onChanges)}}}};var RealtimeContext=createContext3(null);var RealtimeProvider=({children,...options})=>{const[shared]=useState3(()=>shareClient(options));useEffect2(()=>{shared.update(options)});useEffect2(()=>{shared.acquire();return shared.release},[shared]);return jsx4(RealtimeContext.Provider,{value:shared,children})};var useRealtimeClient=()=>{const client=useContext3(RealtimeContext);if(client===null){throw new Error("useRealtimeClient requires a RealtimeProvider")}return client};import{realtimeTopicKey}from"@collective-intelligence/external-apps-client-sdk";import{useEffect as useEffect3,useRef,useState as useState4}from"react";var useRealtimeTopic=(topic,onChanges)=>{const client=useRealtimeClient();const latest=useRef(onChanges);const key=topic===null?null:realtimeTopicKey(topic);const[subscribed,setSubscribed]=useState4({key,topic});if(subscribed.key!==key){setSubscribed({key,topic})}useEffect3(()=>{latest.current=onChanges});useEffect3(()=>subscribed.topic===null?undefined:client.subscribe(subscribed.topic,(changes)=>latest.current(changes)),[client,subscribed])};"use client";var clientSdkReactEntrypoint="react";"use client";var{AgentPrompt:AgentPrompt2,AgentPromptPrimitive:AgentPromptPrimitive2,CollectiveIntelligenceLoginProvider:CollectiveIntelligenceLoginProvider2,CollectiveIntelligenceProvider:CollectiveIntelligenceProvider2,EntityForm,EntityList,EntityTable,LoginButton:LoginButton2,LoginCallback:LoginCallback2,LoginCallbackPrimitive:LoginCallbackPrimitive2,RealtimeProvider:RealtimeProvider2,SessionGate:SessionGate2,clientSdkReactEntrypoint:clientSdkReactEntrypoint2,createDelegatedEntitySource,createPromptKeyHandler:createPromptKeyHandler2,defineEntity,useAgents:useAgents2,useAttachments:useAttachments2,useClientContext:useClientContext2,useCollectiveIntelligenceAuth:useCollectiveIntelligenceAuth2,useCollectiveIntelligenceClient:useCollectiveIntelligenceClient2,useEntityViewState,useKnowledge:useKnowledge2,useMemoryEntityViewState,useOrganizationClient:useOrganizationClient2,useRealtimeClient:useRealtimeClient2,useRealtimeTopic:useRealtimeTopic2,useRuns:useRuns2,useSession:useSession2,useSkills:useSkills2,useWorkflows:useWorkflows2,useAgentInvocation:useAgentInvocation2}=exports_src;export{AgentPrompt2 as AgentPrompt,AgentPromptPrimitive2 as AgentPromptPrimitive,CollectiveIntelligenceLoginProvider2 as CollectiveIntelligenceLoginProvider,CollectiveIntelligenceProvider2 as CollectiveIntelligenceProvider,EntityForm,EntityList,EntityTable,LoginButton2 as LoginButton,LoginCallback2 as LoginCallback,LoginCallbackPrimitive2 as LoginCallbackPrimitive,RealtimeProvider2 as RealtimeProvider,SessionGate2 as SessionGate,clientSdkReactEntrypoint2 as clientSdkReactEntrypoint,createDelegatedEntitySource,createPromptKeyHandler2 as createPromptKeyHandler,defineEntity,useAgentInvocation2 as useAgentInvocation,useAgents2 as useAgents,useAttachments2 as useAttachments,useClientContext2 as useClientContext,useCollectiveIntelligenceAuth2 as useCollectiveIntelligenceAuth,useCollectiveIntelligenceClient2 as useCollectiveIntelligenceClient,useEntityViewState,useKnowledge2 as useKnowledge,useMemoryEntityViewState,useOrganizationClient2 as useOrganizationClient,useRealtimeClient2 as useRealtimeClient,useRealtimeTopic2 as useRealtimeTopic,useRuns2 as useRuns,useSession2 as useSession,useSkills2 as useSkills,useWorkflows2 as useWorkflows};
package/dist/resources.js CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{resourceKeys,ResourceQueryError2,unwrapResourceResult2,createResourceListQueryOptions,mapResourceAuthState2,hasResourceCapability2,clearProtectedResourceQueries,createDelegatedEntitySource,defineEntity2,useEntityUpdate2,useEntityCreate2,useEntityDelete2,useEntityList2,useEntityRecord2,useEntityViewState2,useMemoryEntityViewState2,EntityTable2,EntityList2,EntityForm2}from"./index-wb56c1cj.js";import{__export}from"./index-6ra894v2.js";var exports_resources={};__export(exports_resources,{EntityForm:()=>EntityForm2,EntityList:()=>EntityList2,EntityTable:()=>EntityTable2,ResourceCapabilityAction:()=>ResourceCapabilityAction,ResourceFilter:()=>ResourceFilter,ResourceLifecycleAction:()=>ResourceLifecycleAction,ResourceList:()=>ResourceList,ResourcePagination:()=>ResourcePagination,ResourceProvider:()=>ResourceProvider,ResourceQueryError:()=>ResourceQueryError2,ResourceTable:()=>ResourceTable,createDelegatedEntitySource:()=>createDelegatedEntitySource,defineEntity:()=>defineEntity2,hasResourceCapability:()=>hasResourceCapability2,mapResourceAuthState:()=>mapResourceAuthState2,unwrapResourceResult:()=>unwrapResourceResult2,useEntityCreate:()=>useEntityCreate2,useEntityDelete:()=>useEntityDelete2,useEntityList:()=>useEntityList2,useEntityRecord:()=>useEntityRecord2,useEntityUpdate:()=>useEntityUpdate2,useEntityViewState:()=>useEntityViewState2,useMemoryEntityViewState:()=>useMemoryEntityViewState2});import{useMutation,useQuery,useQueryClient as useQueryClient2}from"@tanstack/react-query";import{mutationOptions}from"@tanstack/react-query";var invalidateResource=async(options)=>{await options.queryClient.invalidateQueries({queryKey:resourceKeys.resource(options.organizationId,options.client.definition.id,options.client.definition.version)})};var createResourceMutationOptions=(options)=>mutationOptions({mutationFn:async(input)=>{let result;switch(options.operation){case"hard_delete":{unwrapResourceResult2(await options.client.hardDelete(input));break}case"restore":{result=unwrapResourceResult2(await options.client.restore(input));break}case"soft_delete":{result=unwrapResourceResult2(await options.client.softDelete(input));break}default:{throw new TypeError(`Unknown resource operation: ${String(options.operation)}`)}}return result},mutationKey:[...resourceKeys.resource(options.organizationId,options.client.definition.id,options.client.definition.version),"mutations",options.operation],onSuccess:async()=>{await invalidateResource(options)}});import{useQueryClient}from"@tanstack/react-query";import{createContext,useContext,useEffect,useMemo,useRef}from"react";import{jsx}from"react/jsx-runtime";var useResourceQueryCleanup=(queryClient,authStatus,organizationId)=>{const previousOrganizationId=useRef(null);const input=useMemo(()=>({authStatus,organizationId}),[authStatus,organizationId]);useEffect(()=>{const previous=previousOrganizationId.current;previousOrganizationId.current=input.organizationId;if(input.authStatus!=="authenticated"){clearProtectedResourceQueries(queryClient);return}if(previous!==null&&previous!==input.organizationId){clearProtectedResourceQueries(queryClient,previous)}},[input,queryClient])};var ResourceContext=createContext(null);var ResourceProvider=({authState,capabilities,children,organizationId})=>{const queryClient=useQueryClient();useResourceQueryCleanup(queryClient,authState.status,organizationId);const value=useMemo(()=>({authState,capabilities,organizationId}),[authState,capabilities,organizationId]);return jsx(ResourceContext.Provider,{value,children})};var useResourceContext=()=>{const value=useContext(ResourceContext);if(value===null){throw new Error("ResourceProvider must wrap resource bindings")}return value};var authStateForError=(error,fallback)=>error instanceof ResourceQueryError2?mapResourceAuthState2({correlationId:error.correlationId,error:error.resourceError,ok:false}):fallback;var useResourceList=(client,query)=>{const context=useResourceContext();const result=useQuery({...createResourceListQueryOptions({client,organizationId:context.organizationId,query}),enabled:context.authState.status==="authenticated"});return{...result,authState:authStateForError(result.error,context.authState)}};var useResourceLifecycleMutation=(client,operation)=>{const{capabilities,organizationId}=useResourceContext();const queryClient=useQueryClient2();const mutation=useMutation(createResourceMutationOptions({client,operation,organizationId,queryClient}));let capability;if(operation==="hard_delete"){capability="hardDelete"}else if(operation==="soft_delete"){capability="softDelete"}else{capability=operation}return{...mutation,available:capabilities[capability]===true}};import{jsx as jsx2,jsxs,Fragment}from"react/jsx-runtime";var nextQuery=(query,result)=>{if(result.pagination==="cursor"){return result.nextCursor===undefined?undefined:{...query,pagination:{cursor:result.nextCursor,limit:query.pagination.mode==="cursor"?query.pagination.limit:25,mode:"cursor"}}}return result.page>=result.totalPages?undefined:{...query,pagination:{mode:"page",page:result.page+1,pageSize:result.pageSize}}};var previousQuery=(query,result)=>result.pagination==="page"&&result.page>1?{...query,pagination:{mode:"page",page:result.page-1,pageSize:result.pageSize}}:undefined;var DefaultStatus=({authState,error,pending})=>{let message=authState.status;if(authState.status==="authenticated"){message=pending?"Loading resources":error?.message??""}return jsx2("output",{"aria-live":"polite",children:message})};var ResourceList=({client,components,onQueryChange,query,renderItem})=>{const resourceQuery=useResourceList(client,query);const Status=components.Status??DefaultStatus;if(resourceQuery.authState.status!=="authenticated"||resourceQuery.isPending||resourceQuery.error!==null){return jsx2(Status,{authState:resourceQuery.authState,pending:resourceQuery.isPending,...resourceQuery.error===null?{}:{error:resourceQuery.error}})}const{List}=components;const{Pagination}=components;const result=resourceQuery.data;const next=nextQuery(query,result);const previous=previousQuery(query,result);return jsxs(Fragment,{children:[jsx2(List,{getItemKey:(item)=>item.id,items:result.items,renderItem}),Pagination===undefined?null:jsx2(Pagination,{hasNextPage:next!==undefined,hasPreviousPage:previous!==undefined,isPending:resourceQuery.isFetching,onNext:()=>{if(next!==undefined){onQueryChange?.(next)}},onPrevious:()=>{if(previous!==undefined){onQueryChange?.(previous)}},...result.pagination==="page"?{currentPage:result.page}:{}})]})};var ResourceCapabilityAction=({capability,children,components,unsupported="disable"})=>{const{capabilities}=useResourceContext();const supported=capabilities[capability]===true;if(!supported&&unsupported==="hide"){return null}const{Action}=components;return jsx2(Action,{disabled:!supported,children})};var ResourceFilter=({components,label="Search resources",onQueryChange,query})=>{const{Filter}=components;const{textSearch:_textSearch,...queryWithoutTextSearch}=query;return jsx2(Filter,{label,onChange:(value)=>{onQueryChange(value===""?queryWithoutTextSearch:{...query,textSearch:value})},value:query.textSearch??""})};var ResourcePagination=({components,isPending=false,onQueryChange,query,result})=>{const{Pagination}=components;const next=nextQuery(query,result);const previous=previousQuery(query,result);return jsx2(Pagination,{hasNextPage:next!==undefined,hasPreviousPage:previous!==undefined,isPending,onNext:()=>{if(next!==undefined){onQueryChange(next)}},onPrevious:()=>{if(previous!==undefined){onQueryChange(previous)}},...result.pagination==="page"?{currentPage:result.page}:{}})};var ResourceTable=({caption,client,columns,components,query})=>{const resourceQuery=useResourceList(client,query);const Status=components.Status??DefaultStatus;if(resourceQuery.authState.status!=="authenticated"||resourceQuery.isPending||resourceQuery.error!==null){return jsx2(Status,{authState:resourceQuery.authState,pending:resourceQuery.isPending,...resourceQuery.error===null?{}:{error:resourceQuery.error}})}const{Table}=components;return jsx2(Table,{caption,columns,getRowKey:(row)=>row.id,renderCell:(row,column)=>column.render(row),rows:resourceQuery.data.items})};var ResourceLifecycleAction=({children,client,components,input,operation,unsupported="disable"})=>{const mutation=useResourceLifecycleMutation(client,operation);if(!mutation.available&&unsupported==="hide"){return null}const{Action}=components;return jsx2(Action,{disabled:!mutation.available,onClick:()=>{mutation.mutate(input)},pending:mutation.isPending,children})};"use client";var{defineEntity,EntityForm,EntityList,EntityTable,ResourceCapabilityAction:ResourceCapabilityAction2,ResourceFilter:ResourceFilter2,ResourceLifecycleAction:ResourceLifecycleAction2,ResourceList:ResourceList2,ResourcePagination:ResourcePagination2,ResourceProvider:ResourceProvider2,ResourceQueryError,ResourceTable:ResourceTable2,hasResourceCapability,mapResourceAuthState,unwrapResourceResult,useEntityCreate,useEntityDelete,useEntityList,useEntityRecord,useEntityUpdate,useEntityViewState,useMemoryEntityViewState}=exports_resources;export{EntityForm,EntityList,EntityTable,ResourceCapabilityAction2 as ResourceCapabilityAction,ResourceFilter2 as ResourceFilter,ResourceLifecycleAction2 as ResourceLifecycleAction,ResourceList2 as ResourceList,ResourcePagination2 as ResourcePagination,ResourceProvider2 as ResourceProvider,ResourceQueryError,ResourceTable2 as ResourceTable,defineEntity,hasResourceCapability,mapResourceAuthState,unwrapResourceResult,useEntityCreate,useEntityDelete,useEntityList,useEntityRecord,useEntityUpdate,useEntityViewState,useMemoryEntityViewState};
2
+ import{resourceKeys,ResourceQueryError2,unwrapResourceResult2,createResourceListQueryOptions,mapResourceAuthState2,hasResourceCapability2,clearProtectedResourceQueries,createDelegatedEntitySource2,defineEntity2,useEntityUpdate2,useEntityCreate2,useEntityDelete2,useEntityList2,useEntityRecord2,useEntityViewState2,useMemoryEntityViewState2,EntityTable2,EntityList2,EntityForm2}from"./index-qb0zr9z9.js";import{__export}from"./index-6ra894v2.js";var exports_resources={};__export(exports_resources,{EntityForm:()=>EntityForm2,EntityList:()=>EntityList2,EntityTable:()=>EntityTable2,ResourceCapabilityAction:()=>ResourceCapabilityAction,ResourceFilter:()=>ResourceFilter,ResourceLifecycleAction:()=>ResourceLifecycleAction,ResourceList:()=>ResourceList,ResourcePagination:()=>ResourcePagination,ResourceProvider:()=>ResourceProvider,ResourceQueryError:()=>ResourceQueryError2,ResourceTable:()=>ResourceTable,createDelegatedEntitySource:()=>createDelegatedEntitySource2,defineEntity:()=>defineEntity2,hasResourceCapability:()=>hasResourceCapability2,mapResourceAuthState:()=>mapResourceAuthState2,unwrapResourceResult:()=>unwrapResourceResult2,useEntityCreate:()=>useEntityCreate2,useEntityDelete:()=>useEntityDelete2,useEntityList:()=>useEntityList2,useEntityRecord:()=>useEntityRecord2,useEntityUpdate:()=>useEntityUpdate2,useEntityViewState:()=>useEntityViewState2,useMemoryEntityViewState:()=>useMemoryEntityViewState2});import{useMutation,useQuery,useQueryClient as useQueryClient2}from"@tanstack/react-query";import{mutationOptions}from"@tanstack/react-query";var invalidateResource=async(options)=>{await options.queryClient.invalidateQueries({queryKey:resourceKeys.resource(options.organizationId,options.client.definition.id,options.client.definition.version)})};var createResourceMutationOptions=(options)=>mutationOptions({mutationFn:async(input)=>{let result;switch(options.operation){case"hard_delete":{unwrapResourceResult2(await options.client.hardDelete(input));break}case"restore":{result=unwrapResourceResult2(await options.client.restore(input));break}case"soft_delete":{result=unwrapResourceResult2(await options.client.softDelete(input));break}default:{throw new TypeError(`Unknown resource operation: ${String(options.operation)}`)}}return result},mutationKey:[...resourceKeys.resource(options.organizationId,options.client.definition.id,options.client.definition.version),"mutations",options.operation],onSuccess:async()=>{await invalidateResource(options)}});import{useQueryClient}from"@tanstack/react-query";import{createContext,useContext,useEffect,useMemo,useRef}from"react";import{jsx}from"react/jsx-runtime";var useResourceQueryCleanup=(queryClient,authStatus,organizationId)=>{const previousOrganizationId=useRef(null);const input=useMemo(()=>({authStatus,organizationId}),[authStatus,organizationId]);useEffect(()=>{const previous=previousOrganizationId.current;previousOrganizationId.current=input.organizationId;if(input.authStatus!=="authenticated"){clearProtectedResourceQueries(queryClient);return}if(previous!==null&&previous!==input.organizationId){clearProtectedResourceQueries(queryClient,previous)}},[input,queryClient])};var ResourceContext=createContext(null);var ResourceProvider=({authState,capabilities,children,organizationId})=>{const queryClient=useQueryClient();useResourceQueryCleanup(queryClient,authState.status,organizationId);const value=useMemo(()=>({authState,capabilities,organizationId}),[authState,capabilities,organizationId]);return jsx(ResourceContext.Provider,{value,children})};var useResourceContext=()=>{const value=useContext(ResourceContext);if(value===null){throw new Error("ResourceProvider must wrap resource bindings")}return value};var authStateForError=(error,fallback)=>error instanceof ResourceQueryError2?mapResourceAuthState2({correlationId:error.correlationId,error:error.resourceError,ok:false}):fallback;var useResourceList=(client,query)=>{const context=useResourceContext();const result=useQuery({...createResourceListQueryOptions({client,organizationId:context.organizationId,query}),enabled:context.authState.status==="authenticated"});return{...result,authState:authStateForError(result.error,context.authState)}};var useResourceLifecycleMutation=(client,operation)=>{const{capabilities,organizationId}=useResourceContext();const queryClient=useQueryClient2();const mutation=useMutation(createResourceMutationOptions({client,operation,organizationId,queryClient}));let capability;if(operation==="hard_delete"){capability="hardDelete"}else if(operation==="soft_delete"){capability="softDelete"}else{capability=operation}return{...mutation,available:capabilities[capability]===true}};import{jsx as jsx2,jsxs,Fragment}from"react/jsx-runtime";var nextQuery=(query,result)=>{if(result.pagination==="cursor"){return result.nextCursor===undefined?undefined:{...query,pagination:{cursor:result.nextCursor,limit:query.pagination.mode==="cursor"?query.pagination.limit:25,mode:"cursor"}}}return result.page>=result.totalPages?undefined:{...query,pagination:{mode:"page",page:result.page+1,pageSize:result.pageSize}}};var previousQuery=(query,result)=>result.pagination==="page"&&result.page>1?{...query,pagination:{mode:"page",page:result.page-1,pageSize:result.pageSize}}:undefined;var DefaultStatus=({authState,error,pending})=>{let message=authState.status;if(authState.status==="authenticated"){message=pending?"Loading resources":error?.message??""}return jsx2("output",{"aria-live":"polite",children:message})};var ResourceList=({client,components,onQueryChange,query,renderItem})=>{const resourceQuery=useResourceList(client,query);const Status=components.Status??DefaultStatus;if(resourceQuery.authState.status!=="authenticated"||resourceQuery.isPending||resourceQuery.error!==null){return jsx2(Status,{authState:resourceQuery.authState,pending:resourceQuery.isPending,...resourceQuery.error===null?{}:{error:resourceQuery.error}})}const{List}=components;const{Pagination}=components;const result=resourceQuery.data;const next=nextQuery(query,result);const previous=previousQuery(query,result);return jsxs(Fragment,{children:[jsx2(List,{getItemKey:(item)=>item.id,items:result.items,renderItem}),Pagination===undefined?null:jsx2(Pagination,{hasNextPage:next!==undefined,hasPreviousPage:previous!==undefined,isPending:resourceQuery.isFetching,onNext:()=>{if(next!==undefined){onQueryChange?.(next)}},onPrevious:()=>{if(previous!==undefined){onQueryChange?.(previous)}},...result.pagination==="page"?{currentPage:result.page}:{}})]})};var ResourceCapabilityAction=({capability,children,components,unsupported="disable"})=>{const{capabilities}=useResourceContext();const supported=capabilities[capability]===true;if(!supported&&unsupported==="hide"){return null}const{Action}=components;return jsx2(Action,{disabled:!supported,children})};var ResourceFilter=({components,label="Search resources",onQueryChange,query})=>{const{Filter}=components;const{textSearch:_textSearch,...queryWithoutTextSearch}=query;return jsx2(Filter,{label,onChange:(value)=>{onQueryChange(value===""?queryWithoutTextSearch:{...query,textSearch:value})},value:query.textSearch??""})};var ResourcePagination=({components,isPending=false,onQueryChange,query,result})=>{const{Pagination}=components;const next=nextQuery(query,result);const previous=previousQuery(query,result);return jsx2(Pagination,{hasNextPage:next!==undefined,hasPreviousPage:previous!==undefined,isPending,onNext:()=>{if(next!==undefined){onQueryChange(next)}},onPrevious:()=>{if(previous!==undefined){onQueryChange(previous)}},...result.pagination==="page"?{currentPage:result.page}:{}})};var ResourceTable=({caption,client,columns,components,query})=>{const resourceQuery=useResourceList(client,query);const Status=components.Status??DefaultStatus;if(resourceQuery.authState.status!=="authenticated"||resourceQuery.isPending||resourceQuery.error!==null){return jsx2(Status,{authState:resourceQuery.authState,pending:resourceQuery.isPending,...resourceQuery.error===null?{}:{error:resourceQuery.error}})}const{Table}=components;return jsx2(Table,{caption,columns,getRowKey:(row)=>row.id,renderCell:(row,column)=>column.render(row),rows:resourceQuery.data.items})};var ResourceLifecycleAction=({children,client,components,input,operation,unsupported="disable"})=>{const mutation=useResourceLifecycleMutation(client,operation);if(!mutation.available&&unsupported==="hide"){return null}const{Action}=components;return jsx2(Action,{disabled:!mutation.available,onClick:()=>{mutation.mutate(input)},pending:mutation.isPending,children})};"use client";var{createDelegatedEntitySource,defineEntity,EntityForm,EntityList,EntityTable,ResourceCapabilityAction:ResourceCapabilityAction2,ResourceFilter:ResourceFilter2,ResourceLifecycleAction:ResourceLifecycleAction2,ResourceList:ResourceList2,ResourcePagination:ResourcePagination2,ResourceProvider:ResourceProvider2,ResourceQueryError,ResourceTable:ResourceTable2,hasResourceCapability,mapResourceAuthState,unwrapResourceResult,useEntityCreate,useEntityDelete,useEntityList,useEntityRecord,useEntityUpdate,useEntityViewState,useMemoryEntityViewState}=exports_resources;export{EntityForm,EntityList,EntityTable,ResourceCapabilityAction2 as ResourceCapabilityAction,ResourceFilter2 as ResourceFilter,ResourceLifecycleAction2 as ResourceLifecycleAction,ResourceList2 as ResourceList,ResourcePagination2 as ResourcePagination,ResourceProvider2 as ResourceProvider,ResourceQueryError,ResourceTable2 as ResourceTable,createDelegatedEntitySource,defineEntity,hasResourceCapability,mapResourceAuthState,unwrapResourceResult,useEntityCreate,useEntityDelete,useEntityList,useEntityRecord,useEntityUpdate,useEntityViewState,useMemoryEntityViewState};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@collective-intelligence/external-apps-client-sdk-react",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "React bindings for Collective Intelligence external applications.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -85,5 +85,5 @@
85
85
  "vitest": "4.1.10",
86
86
  "xstate": "5.33.3"
87
87
  },
88
- "gitHead": "bfe1f5e741d70b6e5a5072e411d84b00e737670d"
88
+ "gitHead": "1d9a87941cea1213c5525de4b18a44fbe9fc8cd6"
89
89
  }
@@ -1,2 +0,0 @@
1
- import{createEntityHttpTransport,createResourceClient}from"@collective-intelligence/external-apps-client-sdk";import{useQueryClient}from"@tanstack/react-query";import*as ManagedRuntime from"effect/ManagedRuntime";import{createContext,useContext,useLayoutEffect,useMemo,useSyncExternalStore}from"react";import{queryOptions}from"@tanstack/react-query";var rootKey=["ci-resources"];var resourceKeys={all:rootKey,list:(organizationId,resourceId,version,query)=>[...resourceKeys.lists(organizationId,resourceId,version),query],lists:(organizationId,resourceId,version)=>[...resourceKeys.resource(organizationId,resourceId,version),"lists"],organization:(organizationId)=>[...rootKey,"organizations",organizationId],record:(organizationId,resourceId,version,recordId,includeDeleted=false)=>[...resourceKeys.records(organizationId,resourceId,version),recordId,includeDeleted],records:(organizationId,resourceId,version)=>[...resourceKeys.resource(organizationId,resourceId,version),"records"],resource:(organizationId,resourceId,version)=>[...resourceKeys.organization(organizationId),"resources",resourceId,"versions",version]};class ResourceQueryError2 extends Error{correlationId;resourceError;constructor(correlationId,error){super(error.message);this.name="ResourceQueryError";this.correlationId=correlationId;this.resourceError=error}}var unwrapResourceResult2=(result)=>{if(!result.ok){throw new ResourceQueryError2(result.correlationId,result.error)}return result.value};var createResourceListQueryOptions=(options)=>queryOptions({queryFn:async({signal})=>unwrapResourceResult2(await options.client.list(options.query,{signal})),queryKey:resourceKeys.list(options.organizationId,options.client.definition.id,options.client.definition.version,options.query)});var mapResourceAuthState2=(source)=>{if("ok"in source){if(source.ok){return{status:"authenticated"}}if(source.error.code==="forbidden"){return{status:"forbidden"}}if(source.error.code==="unauthenticated"){return{status:"unauthenticated"}}return{status:"authenticated"}}if(source.status==="authenticated"){return{status:"authenticated"}}if(source.status==="expired"){return{status:"expired"}}if(source.status==="error"&&source.error.code==="reauthorization_required"){return{status:"reauthentication_required"}}return{status:"unauthenticated"}};var hasResourceCapability2=(capabilities,capability)=>capabilities[capability]===true;var clearProtectedResourceQueries=async(queryClient,organizationId)=>{const queryKey=organizationId===undefined?resourceKeys.all:resourceKeys.organization(organizationId);await queryClient.cancelQueries({queryKey});queryClient.removeQueries({queryKey})};import{hashKey}from"@tanstack/react-query";import*as Context from"effect/Context";import*as Effect from"effect/Effect";import*as Layer from"effect/Layer";import*as RcMap from"effect/RcMap";import*as Semaphore from"effect/Semaphore";class WriteLock extends Context.Service()("@collective-intelligence/external-apps-client-sdk-react/WriteLock"){}var idleTimeToLive="30 seconds";var layer=Layer.effect(WriteLock,Effect.gen(function*makeWriteLock(){const locks=yield*RcMap.make({idleTimeToLive,lookup:(_hash)=>Semaphore.make(1)});const holding=(hash)=>(self)=>Effect.scoped(Effect.flatMap(RcMap.get(locks,hash),(lock)=>lock.withPermits(1)(self)));return WriteLock.of({settled:(queryKey)=>Effect.flatMap(RcMap.keys(locks),(hashes)=>{const hash=hashKey(queryKey);const below=`${hash.slice(0,-1)},`;return Effect.forEach([...hashes].filter((held)=>held===hash||held.startsWith(below)),(held)=>holding(held)(Effect.void),{discard:true})}),withRecord:(recordKey)=>holding(hashKey(recordKey))})}));var writesSettled=(queryKey)=>Effect.gen(function*awaitWrites(){const lock=yield*WriteLock;yield*lock.settled(queryKey)});import{jsx}from"react/jsx-runtime";var entityScopeError=(outcome="not_dispatched")=>new ResourceQueryError2("client-scope",{code:"unauthenticated",message:"The authenticated entity source has changed",outcome,retryable:false});var identityKey=(state)=>state.status==="authenticated"?[state.identity.sourceId,state.identity.applicationId,state.identity.userId,state.identity.organizationId]:[state.status];var EntityContext=createContext(null);var createRuntime=(source,state)=>{let active=true;let onWriteFailed;return{activate:()=>{active=true},current:()=>active&&source.getSnapshot()===state&&state.status==="authenticated",deactivate:()=>{active=false},formScope:globalThis.crypto.randomUUID(),key:identityKey(state),reportWriteFailures:(listener)=>{onWriteFailed=listener},source,state,writeFailed:(event)=>{onWriteFailed?.(event)},writeLock:ManagedRuntime.make(layer)}};var EntityRuntimeProvider=({source,onWriteFailed,children})=>{const queryClient=useQueryClient();const state=useSyncExternalStore(source.subscribe,source.getSnapshot,source.getSnapshot);const runtime=useMemo(()=>createRuntime(source,state),[source,state]);useLayoutEffect(()=>{runtime.reportWriteFailures(onWriteFailed)},[runtime,onWriteFailed]);useLayoutEffect(()=>{runtime.activate();return()=>{runtime.deactivate();queryClient.cancelQueries({queryKey:["ci-entities",...runtime.key]});queryClient.removeQueries({queryKey:["ci-entities",...runtime.key]})}},[queryClient,runtime]);return jsx(EntityContext.Provider,{value:runtime,children})};var useEntityRuntime=()=>{const context=useContext(EntityContext);if(context===null){throw new Error("Configure an entity source on CollectiveIntelligenceProvider")}return context};var defaultPathFor=(contract)=>`/api/resources/${contract.id}`;var createDelegatedEntitySource=(options)=>{const fetch=options.fetch??globalThis.fetch;const pathFor=options.pathFor??defaultPathFor;const sourceId=options.sourceId??`${options.origin}/api/resources`;let cached;const snapshot=()=>{const identity=options.getIdentity();const status=options.getStatus();const next=status==="authenticated"&&identity!==null?{identity:{applicationId:options.applicationId,organizationId:identity.organizationId,sourceId,userId:identity.userId},status:"authenticated"}:{status:status==="expired"?"expired":"unauthenticated"};if(cached!==undefined&&identityKey(cached).join("\x00")===identityKey(next).join("\x00")){return cached}cached=next;return next};return{bind:(contract)=>createResourceClient({definition:contract,protocol:"entity",transport:createEntityHttpTransport({authentication:{credentials:"same-origin",mode:"server_delegated"},destination:{endpoint:new URL(pathFor(contract),options.origin).href,kind:"gateway"},fetch})}),getSnapshot:snapshot,subscribe:options.subscribe}};var assertConfiguredFields=(config)=>{const declared=new Set(Object.keys(config.fields));const referenced=[...config.table.columns,...Object.values(config.table.variants??{}).flatMap((variant)=>variant.columns),config.list.title,...config.list.description===undefined?[]:[config.list.description],...config.forms.create.fields,...config.forms.update.fields];const unknown=referenced.find((field)=>!declared.has(field));if(unknown!==undefined){throw new Error(`Entity view references unconfigured field: ${unknown}`)}};var defineEntity2=(declaration)=>{assertConfiguredFields(declaration.config);const schemaFields=new Set(Object.keys(declaration.contract.schemas.entity.properties??{}));const unknown=Object.keys(declaration.config.fields).find((field)=>!schemaFields.has(field));if(unknown!==undefined){throw new Error(`Configured field is absent from the entity schema: ${unknown}`)}return Object.freeze(declaration)};import{ResourceFilterPrimitive,ResourceFiltersBar,ResourceFormPrimitive,ResourceListPrimitive,ResourcePaginationPrimitive,ResourceTablePrimitive}from"@collective-intelligence/ui-react/resources";import{useMemo as useMemo5,useState as useState2}from"react";import{useIsMutating,useMutation,useQueryClient as useQueryClient2}from"@tanstack/react-query";import{useMemo as useMemo2,useRef}from"react";import{CiError,CiErrorCode,CiTransportError}from"@collective-intelligence/external-apps-client-sdk/effect";import*as Effect2 from"effect/Effect";import*as Exit from"effect/Exit";import*as Schema from"effect/Schema";var heldWrites=new WeakMap;var fetchedOrder=new WeakMap;var orderOf=(page)=>fetchedOrder.get(page)??page.items.map((row)=>row.id);var withOrder=(page,order)=>{fetchedOrder.set(page,order);return page};var store=(queryClient,key,data,next,write,holds)=>{const writes=new Set(heldWrites.get(data));if(holds){writes.add(write)}else{writes.delete(write)}const stored=next===data?data:queryClient.setQueryData(key,next);if(stored!==undefined){heldWrites.set(stored,writes);const order=fetchedOrder.get(next)??fetchedOrder.get(data);if(order!==undefined){fetchedOrder.set(stored,order)}}};var touch=(queryClient,key,snapshot,edit,write,optimistic)=>{store(queryClient,key,snapshot,optimistic?edit.pending(snapshot):snapshot,write,true);return(confirmed)=>{const data=queryClient.getQueryData(key);if(data!==undefined&&heldWrites.get(data)?.has(write)===true){store(queryClient,key,data,edit.settled(data,snapshot,confirmed),write,false)}}};var predicted=(change,record)=>change.operation==="update"?{...record,value:{...record.value,...change.input.value}}:{...record,deletedAt:new Date().toISOString()};var pendingRow=(input)=>({id:input.idempotencyKey,revision:"",value:input.value});var replaceItem=(page,id,replace)=>page.items.some((item)=>item.id===id)?{...page,items:page.items.map((item)=>item.id===id?replace(item):item)}:page;var removeItem=(page,id)=>page.items.some((item)=>item.id===id)?{...page,items:page.items.filter((item)=>item.id!==id)}:page;var idsAfter=(ids,id)=>{const index=ids.indexOf(id);return index===-1?[]:ids.slice(index+1)};var restoreItem=(page,snapshot,id)=>{const item=snapshot.items.find((row)=>row.id===id);if(item===undefined||page.items.some((row)=>row.id===id)){return page}const later=new Set(idsAfter(orderOf(page),id));const at=page.items.findIndex((row)=>later.has(row.id));const items=[...page.items];items.splice(at===-1?items.length:at,0,item);return{...page,items}};var pageEdit=(change)=>{if(change.operation==="update"){const{id}=change.input;return{pending:(page)=>replaceItem(page,id,(item)=>predicted(change,item)),settled:(page,snapshot,confirmed)=>replaceItem(page,id,(item)=>confirmed??snapshot.items.find((row)=>row.id===id)??item)}}if(change.operation==="delete"){const{id}=change.input;return{pending:(page)=>removeItem(page,id),settled:(page,snapshot,confirmed)=>confirmed===undefined?restoreItem(page,snapshot,id):removeItem(page,id)}}const key=change.input.idempotencyKey;const first=(page,row)=>page.page===1?withOrder({...page,items:[row,...page.items]},[row.id,...orderOf(page)]):page;return{pending:(page)=>first(page,pendingRow(change.input)),settled:(page,_snapshot,confirmed)=>{if(!page.items.some((item)=>item.id===key)){return confirmed===undefined?page:first(page,confirmed)}const order=orderOf(page);return confirmed===undefined?withOrder(removeItem(page,key),order.filter((id)=>id!==key)):withOrder(replaceItem(page,key,()=>confirmed),order.map((id)=>id===key?confirmed.id:id))}}};var recordKeyOf=(resourceKey,change)=>[...resourceKey,"record",change.operation==="create"?change.input.idempotencyKey:change.input.id];var apply=(options,recordKey,write)=>{const{change,optimistic,queryClient,resourceKey}=options;const settles=[];if(change.operation!=="create"){const record=queryClient.getQueryData(recordKey);if(record!==undefined){settles.push(touch(queryClient,recordKey,record,{pending:(data)=>predicted(change,data),settled:(_data,snapshot,confirmed)=>confirmed??snapshot},write,optimistic))}}for(const[key,page]of queryClient.getQueriesData({queryKey:[...resourceKey,"list"]})){if(page!==undefined){fetchedOrder.set(page,orderOf(page));settles.push(touch(queryClient,key,page,pageEdit(change),write,optimistic))}}return settles};var isCiErrorCode=Schema.is(CiErrorCode);var failure=(error)=>error.code==="transport_error"?new CiTransportError({cause:error}):new CiError({code:isCiErrorCode(error.code)?error.code:"invalid_request",details:error.outcome===undefined?{...error.details,resourceCode:error.code}:{...error.details,outcome:error.outcome,resourceCode:error.code},message:error.message,retryable:error.retryable});var inScope=(current)=>Effect2.suspend(()=>current()?Effect2.void:Effect2.fail(entityScopeError()));var write=(options)=>Effect2.gen(function*optimisticWrite(){const lock=yield*WriteLock;const{queryClient,resourceKey}=options;const recordKey=recordKeyOf(resourceKey,options.change);const token=Symbol("optimistic write");return yield*lock.withRecord(recordKey)(Effect2.acquireUseRelease(Effect2.gen(function*acquire(){yield*inScope(options.current);yield*Effect2.promise(()=>Promise.all([queryClient.cancelQueries({exact:true,queryKey:recordKey}),queryClient.cancelQueries({queryKey:[...resourceKey,"list"]})]));yield*inScope(options.current);return apply(options,recordKey,token)}),()=>Effect2.promise(options.execute),(settles,exit)=>Effect2.sync(()=>{const result=Exit.isSuccess(exit)?exit.value:undefined;const confirmed=result?.ok===true?result.value:undefined;for(const settle of settles){settle(confirmed)}if(result?.ok===false&&options.current()){options.onWriteFailed({error:failure(result.error),label:options.label,operation:options.change.operation})}})))}).pipe(Effect2.ensuring(Effect2.sync(()=>{if(options.current()){options.queryClient.invalidateQueries({queryKey:options.resourceKey})}})));var immutable=(value)=>{if(value!==null&&typeof value==="object"){for(const child of Object.values(value)){immutable(child)}Object.freeze(value)}return value};var useEntityMutation=(contract,options)=>{const runtime=useEntityRuntime();const queryClient=useQueryClient2();const client=useMemo2(()=>runtime.source.bind(contract),[runtime,contract]);const resourceKey=["ci-entities",...runtime.key,contract.id,contract.version];const mutationKey=[...resourceKey,"write",options.id??"create"];const lastAction=useRef(null);const scopeOptions={};if(options.id!==undefined){scopeOptions.scope={id:JSON.stringify(mutationKey)}}const mutation=useMutation({mutationKey,...scopeOptions,mutationFn:async(action)=>{if(!action.current()){throw entityScopeError()}const result=await action.execute();if(!action.current()){throw entityScopeError("uncertain")}if(!result.ok){throw new ResourceQueryError2(result.correlationId,result.error)}return result},networkMode:"always",retry:false});const pending=useIsMutating({mutationKey})>0;const send=async(action)=>{try{const result=await mutation.mutateAsync(action);if(!action.current()){const error=entityScopeError("uncertain");return{correlationId:error.correlationId,error:error.resourceError,ok:false}}return result}catch(error){if(error instanceof ResourceQueryError2){return{correlationId:error.correlationId,error:error.resourceError,ok:false}}throw error}};const submit=(input)=>{const captured=immutable(structuredClone(options.prepare(input)));const action={current:runtime.current,execute:()=>runtime.writeLock.runPromise(write({change:options.change(captured),current:runtime.current,execute:()=>options.execute(client,captured),label:contract.id,onWriteFailed:runtime.writeFailed,optimistic:options.optimistic??true,queryClient,resourceKey})),input:captured,runtime,target:options.id};lastAction.current=action;return send(action)};const resubmit=()=>{const action=lastAction.current;if(action===null){throw new Error("No submitted entity action to resubmit")}if(action.target!==options.id){throw new Error("The submitted action belongs to a different record")}return send(action)};const current=mutation.variables===undefined||mutation.variables.runtime===runtime&&mutation.variables.target===options.id&&mutation.variables.current();const error=current&&mutation.error instanceof ResourceQueryError2?mutation.error:null;const failureStatus=()=>{if(error?.resourceError.outcome==="uncertain"){return"uncertain"}if(error?.resourceError.code==="conflict"){return"conflict"}return"rejected"};const status=mutation.isError?failureStatus():mutation.status;return{available:runtime.state.status==="authenticated"&&client.definition.capabilities[options.operation]===true,data:current?mutation.data?.value:undefined,error,pending,resubmit,status:current?status:"idle",submit,submitted:current?mutation.variables?.input:undefined}};var useEntityUpdate2=(contract,target)=>useEntityMutation(contract,{change:(input)=>({input,operation:"update"}),execute:(client,input)=>client.update(input),id:target.id,operation:"update",optimistic:target.optimistic,prepare:(input)=>({...input,id:target.id,idempotencyKey:globalThis.crypto.randomUUID()})});var useEntityCreate2=(contract)=>useEntityMutation(contract,{change:(input)=>({input,operation:"create"}),execute:(client,input)=>client.create(input),operation:"create",prepare:(input)=>({...input,idempotencyKey:globalThis.crypto.randomUUID()})});var useEntityDelete2=(contract,target)=>useEntityMutation(contract,{change:(input)=>({input,operation:"delete"}),execute:(client,input)=>client.delete(input),id:target.id,operation:"delete",optimistic:target.optimistic,prepare:(input)=>({...input,id:target.id,idempotencyKey:globalThis.crypto.randomUUID()})});import{useQuery}from"@tanstack/react-query";import{useMemo as useMemo3}from"react";var authStateForError=(error,state)=>{if(error instanceof ResourceQueryError2){if(error.resourceError.code==="forbidden"){return{status:"forbidden"}}if(error.resourceError.code==="unauthenticated"){return{status:"unauthenticated"}}}return state};var useEntityList2=(contract,query)=>{const runtime=useEntityRuntime();const client=useMemo3(()=>runtime.source.bind(contract),[runtime,contract]);const result=useQuery({enabled:runtime.state.status==="authenticated"&&client.definition.capabilities.search,queryFn:async({queryKey,signal})=>{if(!runtime.current()){throw entityScopeError()}await runtime.writeLock.runPromise(writesSettled(queryKey.slice(0,-2)),{signal});const data=unwrapResourceResult2(await client.list(query,{signal}));if(!runtime.current()){throw entityScopeError()}return data},queryKey:["ci-entities",...runtime.key,contract.id,contract.version,"list",query],retry:false});return{authState:authStateForError(result.error,runtime.state),capabilities:client.definition.capabilities,data:result.data,empty:result.data?.items.length===0,error:result.error,loading:result.isLoading,refresh:async()=>{await result.refetch()},refreshing:result.isFetching}};var useEntityRecord2=(contract,input)=>{const runtime=useEntityRuntime();const client=useMemo3(()=>runtime.source.bind(contract),[runtime,contract]);const result=useQuery({enabled:runtime.state.status==="authenticated"&&client.definition.capabilities.get===true,queryFn:async({queryKey,signal})=>{if(!runtime.current()){throw entityScopeError()}await runtime.writeLock.runPromise(writesSettled(queryKey),{signal});const data=unwrapResourceResult2(await client.get(input,{signal}));if(!runtime.current()){throw entityScopeError()}return data},queryKey:["ci-entities",...runtime.key,contract.id,contract.version,"record",input.id],retry:false});return{authState:authStateForError(result.error,runtime.state),capabilities:client.definition.capabilities,data:result.data,error:result.error,loading:result.isLoading,refresh:async()=>{await result.refetch()},refreshing:result.isFetching}};import{createEntityProtocol}from"@collective-intelligence/external-apps-client-sdk/resources";import{createParser,parseAsJson,useQueryStates}from"nuqs";import{useMemo as useMemo4,useState}from"react";var DEFAULT_PAGE_SIZE=25;var namespacePattern=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;var isObject=(value)=>typeof value==="object"&&value!==null&&!Array.isArray(value);var isFilter=(value)=>{if(!isObject(value)){return false}if((value.operator==="and"||value.operator==="or")&&"filters"in value){return Array.isArray(value.filters)&&value.filters.every(isFilter)}if(value.operator==="not"&&"filter"in value){return isFilter(value.filter)}return typeof value.field==="string"&&typeof value.operator==="string"&&(value.operator==="is_null"||value.operator==="is_not_null"||value.operator==="is_empty"||("value"in value))};var isSorts=(value)=>Array.isArray(value)&&value.every((sort)=>isObject(sort)&&typeof sort.field==="string"&&(sort.direction==="asc"||sort.direction==="desc"));var positiveInteger=(maximum=Number.MAX_SAFE_INTEGER)=>createParser({parse:(value)=>{const number=Number(value);return/^[1-9]\d*$/u.test(value)&&Number.isSafeInteger(number)&&number<=maximum?number:null},serialize:String});var pageSizeFor=(value=DEFAULT_PAGE_SIZE)=>Number.isSafeInteger(value)&&value>0&&value<=100?value:DEFAULT_PAGE_SIZE;var parsersFor=(pageSize,contract)=>{const protocol=contract===undefined?undefined:createEntityProtocol(contract);const accepts=(query)=>protocol===undefined||protocol.decodeRequest({operation:"list",query:{pagination:{mode:"page",page:1,pageSize},...query},requestId:"view-state",resourceId:contract?.id}).ok;return{filter:parseAsJson((value)=>isFilter(value)&&accepts({filter:value})?value:null),page:positiveInteger().withDefault(1),pageSize:positiveInteger(100).withDefault(pageSize),sort:parseAsJson((value)=>isSorts(value)&&accepts({sort:value})?value:null).withDefault([]),textSearch:createParser({parse:(value)=>accepts({textSearch:value})?value:null,serialize:(value)=>value}).withDefault("")}};var queryFor=(state)=>{const query={pagination:{mode:"page",page:state.page,pageSize:state.pageSize}};if(state.filter!==null){query.filter=state.filter}if(state.sort.length>0){query.sort=state.sort}if(state.textSearch.trim()!==""){query.textSearch=state.textSearch.trim()}return query};var controller=(state,update)=>({query:queryFor(state),setFilter:(filter)=>update({filter,page:1}),setPage:(page)=>update({page:Math.max(1,page)}),setPageSize:(pageSize)=>update({page:1,pageSize:Math.max(1,Math.min(100,pageSize))}),setSort:(sort)=>update({page:1,sort:[...sort]}),setTextSearch:(textSearch)=>update({page:1,textSearch}),state});var useEntityViewState2=(namespace,input={})=>{if(!namespacePattern.test(namespace)){throw new Error("URL-backed entity views require a stable alphanumeric namespace")}const parsers=useMemo4(()=>parsersFor(pageSizeFor(input.pageSize),input.contract),[input.pageSize,input.contract]);const[state,setState]=useQueryStates(parsers,{clearOnDefault:true,history:"replace",shallow:false,urlKeys:{filter:`${namespace}.filter`,page:`${namespace}.page`,pageSize:`${namespace}.pageSize`,sort:`${namespace}.sort`,textSearch:`${namespace}.textSearch`}});const normalized=useMemo4(()=>({filter:state.filter,page:state.page>0?state.page:1,pageSize:state.pageSize>0&&state.pageSize<=100?state.pageSize:input.pageSize??DEFAULT_PAGE_SIZE,sort:state.sort,textSearch:state.textSearch}),[input.pageSize,state]);return controller(normalized,(next)=>{const{sort,...values}=next;const update=values;if(sort!==undefined){update.sort=[...sort]}setState(update)})};var useMemoryEntityViewState2=(input={})=>{const[state,setState]=useState({filter:null,page:1,pageSize:pageSizeFor(input.pageSize),sort:[],textSearch:""});return controller(state,(next)=>{setState((current)=>({...current,...next}))})};import{jsx as jsx2,jsxs,Fragment}from"react/jsx-runtime";var isObject2=(value)=>value!==null&&typeof value==="object"&&!Array.isArray(value);var schemaProperties=(entity,mode="entity")=>{const properties=entity.contract.schemas[mode]?.properties;return isObject2(properties)?properties:{}};var requiredFields=(entity,mode)=>{const required=entity.contract.schemas[mode]?.required;return new Set(Array.isArray(required)?required.filter((value)=>typeof value==="string"):[])};var scalarTypes=(schema)=>{const{type}=schema;if(typeof type==="string"){return[type]}return Array.isArray(type)?type.filter((value)=>typeof value==="string"):[]};var presentationSchema=(schema)=>{const union=schema.anyOf??schema.oneOf;if(!Array.isArray(union)){return schema}const members=union.filter(isObject2);const values=members.filter((member)=>member.type!=="null");const[value]=values;if(members.length===2&&values.length===1&&value!==undefined){return{...schema,...value,type:[...scalarTypes(value),"null"]}}return schema};var defaultControl=(schema)=>{if(schema.$ref!==undefined||(schema.anyOf!==undefined||schema.oneOf!==undefined)&&schema.type===undefined){return"custom"}if(Array.isArray(schema.enum)){return"select"}const types=scalarTypes(schema);if(types.includes("boolean")){return"checkbox"}if(types.includes("number")||types.includes("integer")){return"number"}if(schema.format==="email"){return"email"}if(schema.format==="date"){return"date"}if(schema.format==="date-time"){return"datetime-local"}return types.some((type)=>type==="object"||type==="array")?"custom":"text"};var configuredControl=(config,schema)=>{switch(config.control){case"text":case"email":case"number":case"checkbox":case"date":case"datetime-local":case"select":case"custom":{return config.control}case undefined:{return defaultControl(schema)}default:{return"custom"}}};var formFields=(entity,mode)=>{const properties=schemaProperties(entity,mode);const entityProperties=schemaProperties(entity);const required=requiredFields(entity,mode);return entity.config.forms[mode].fields.map((name)=>{const config=entity.config.fields[name];if(config===undefined){throw new Error(`Missing entity field configuration: ${name}`)}const candidate=properties[name]??entityProperties[name];const schema=isObject2(candidate)?presentationSchema(candidate):{};const entityField=entityProperties[name];const enums=Array.isArray(schema.enum)?schema.enum.filter((value)=>typeof value==="string"||typeof value==="number"||typeof value==="boolean"):[];return{control:configuredControl(config,schema),label:config.label,name,nullable:scalarTypes(schema).includes("null")||Array.isArray(schema.enum)&&schema.enum.includes(null),options:enums.map((value)=>({label:String(value),value})),readOnly:config.readOnly===true||schema.readOnly===true||isObject2(entityField)&&entityField.readOnly===true,required:required.has(name)}})};var displayValue=(value)=>{if(value===null||value===undefined){return"—"}if(typeof value==="boolean"){return value?"Yes":"No"}return typeof value==="object"?JSON.stringify(value):String(value)};var renderField=(entity,record,name,renderers)=>{const renderer=entity.config.fields[name]?.renderer;return renderer===undefined||renderers?.[renderer]===undefined?displayValue(record.value[name]):renderers[renderer]({field:name,record})};var sortFor=(state,field)=>{const[current]=state.state.sort;return[{direction:current?.field===field&&current.direction==="asc"?"desc":"asc",field}]};var QueryControls=({view})=>jsx2(ResourceFiltersBar,{controls:[{control:jsx2(ResourceFilterPrimitive,{label:"Search",onChange:(value)=>view.setTextSearch(value),value:view.state.textSearch}),fullWidth:true,key:"search"}]});var EntityStatus=({state})=>{if(state.authState.status!=="authenticated"){return jsx2("output",{children:state.authState.status})}if(state.loading){return jsx2("output",{children:"Loading"})}if(state.error!==null){return jsx2("output",{role:"alert",children:state.error.message})}return null};var EntityPagination=({result,view,pending})=>{if(result===undefined||result.pagination!=="page"){return null}return jsx2(ResourcePaginationPrimitive,{currentPage:result.page,totalPages:result.totalPages,hasPreviousPage:result.page>1,hasNextPage:result.page<result.totalPages,isPending:pending,onPageChange:(page)=>view.setPage(page),onPrevious:()=>view.setPage(result.page-1),onNext:()=>view.setPage(result.page+1)})};var ControlledEntityTable=({entity,empty,renderers,variant,view})=>{const result=useEntityList2(entity.contract,view.query);const names=variant===undefined?entity.config.table.columns:entity.config.table.variants?.[variant]?.columns??entity.config.table.columns;const columns=names.map((name)=>({id:name,label:entity.config.fields[name]?.label??name}));const hasStatus=result.authState.status!=="authenticated"||result.loading||result.error!==null;return jsxs("section",{children:[jsx2(QueryControls,{view}),hasStatus?jsx2(EntityStatus,{state:result}):jsxs(Fragment,{children:[jsx2(ResourceTablePrimitive,{columns:columns.map((column)=>({...column,label:entity.contract.query.sortableFields.includes(column.id)?jsx2("button",{type:"button",onClick:()=>view.setSort(sortFor(view,column.id)),children:column.label}):column.label})),empty,getRowKey:(record)=>record.id,renderCell:(record,column)=>{const name=names.find((field)=>field===column.id);return name===undefined?null:renderField(entity,record,name,renderers)},rows:result.data?.items??[]}),jsx2(EntityPagination,{pending:result.refreshing,result:result.data,view})]})]})};var UrlEntityTable=(props)=>jsx2(ControlledEntityTable,{...props,view:useEntityViewState2(props.namespace,{contract:props.entity.contract,pageSize:props.pageSize??25})});var MemoryEntityTable=(props)=>jsx2(ControlledEntityTable,{...props,view:useMemoryEntityViewState2(props.pageSize===undefined?{}:{pageSize:props.pageSize})});var EntityTable2=(props)=>props.viewState==="memory"?jsx2(MemoryEntityTable,{...props}):jsx2(UrlEntityTable,{...props,namespace:props.namespace});var ControlledEntityList=({entity,empty,renderers,view})=>{const result=useEntityList2(entity.contract,view.query);const hasStatus=result.authState.status!=="authenticated"||result.loading||result.error!==null;return jsxs("section",{children:[jsx2(QueryControls,{view}),hasStatus?jsx2(EntityStatus,{state:result}):jsxs(Fragment,{children:[jsx2(ResourceListPrimitive,{empty,getItemKey:(record)=>record.id,items:result.data?.items??[],renderItem:(record)=>jsxs("article",{children:[jsx2("strong",{children:renderField(entity,record,entity.config.list.title,renderers)}),entity.config.list.description===undefined?null:jsx2("p",{children:renderField(entity,record,entity.config.list.description,renderers)})]})}),jsx2(EntityPagination,{pending:result.refreshing,result:result.data,view})]})]})};var UrlEntityList=(props)=>jsx2(ControlledEntityList,{...props,view:useEntityViewState2(props.namespace,{contract:props.entity.contract,pageSize:props.pageSize??25})});var MemoryEntityList=(props)=>jsx2(ControlledEntityList,{...props,view:useMemoryEntityViewState2(props.pageSize===undefined?{}:{pageSize:props.pageSize})});var EntityList2=(props)=>props.viewState==="memory"?jsx2(MemoryEntityList,{...props}):jsx2(UrlEntityList,{...props,namespace:props.namespace});var initialFormValues=(entity,mode,supplied,record)=>{const values={};const properties=schemaProperties(entity,mode);const required=requiredFields(entity,mode);for(const name of entity.config.forms[mode].fields){const schema=properties[name];if(required.has(name)&&isObject2(schema)&&scalarTypes(presentationSchema(schema)).includes("boolean")){values[name]=false}if(isObject2(schema)&&schema.default!==undefined){values[name]=schema.default}if(record?.value[name]!==undefined){values[name]=record.value[name]}if(supplied?.[name]!==undefined){values[name]=supplied[name]}}return values};var controlRenderer=(entity,controls)=>function renderEntityControl(props){const fields=entity.config.fields;const key=fields[props.field.name]?.control;return key===undefined||controls?.[key]===undefined?jsxs("p",{role:"alert",children:["A custom control is required for ",props.field.label,"."]}):controls[key](props)};var mutationMessage=(mutation)=>{if(mutation.status==="conflict"){return"This entity changed. Your draft is preserved."}if(mutation.status==="uncertain"){return"The write outcome is unknown. Resubmit the same action to resolve it."}return mutation.error?.resourceError.message};var writableValues=(fields,values)=>{const writable=new Set(fields.filter((field)=>!field.readOnly).map((field)=>field.name));return Object.fromEntries(Object.entries(values).filter(([name])=>writable.has(name)))};var displayedValues=(fields,values)=>Object.fromEntries(Object.entries(values).map(([name,value])=>{if(typeof value!=="string"||fields.find((field)=>field.name===name)?.control!=="datetime-local"){return[name,value]}const date=new Date(value);if(Number.isNaN(date.getTime())){return[name,value]}return[name,new Date(date.getTime()-date.getTimezoneOffset()*60000).toISOString().slice(0,23)]}));var wireValue=(fields,name,value)=>{if(typeof value!=="string"||value===""||fields.find((field)=>field.name===name)?.control!=="datetime-local"){return value}const date=new Date(value);return Number.isNaN(date.getTime())?value:date.toISOString()};var CreateEntityForm=(props)=>{const mutation=useEntityCreate2(props.entity.contract);const[values,setValues]=useState2(()=>initialFormValues(props.entity,"create",props.initialValues));const fields=useMemo5(()=>formFields(props.entity,"create"),[props.entity]);return jsx2(ResourceFormPrimitive,{label:"Create entity",fields,values:displayedValues(fields,values),disabled:!mutation.available,pending:mutation.pending,error:mutationMessage(mutation),...props.onCancel===undefined?{}:{onCancel:props.onCancel},onChange:(name,value)=>setValues((current)=>({...current,[name]:wireValue(fields,name,value)})),onSubmit:async()=>{const value=writableValues(fields,values);const action=mutation.status==="uncertain"?mutation.resubmit():mutation.submit({value});const result=await action;if(result.ok){props.onSuccess?.(result.value)}},renderControl:controlRenderer(props.entity,props.controls),submitLabel:mutation.status==="uncertain"?"Resubmit":"Create"})};var UpdateEntityForm=(props)=>{const mutation=useEntityUpdate2(props.entity.contract,{id:props.record.id});const[draft,setDraft]=useState2(()=>({expectedRevision:props.record.revision,values:initialFormValues(props.entity,"update",props.initialValues,props.record)}));const{expectedRevision,values}=draft;const fields=useMemo5(()=>formFields(props.entity,"update"),[props.entity]);return jsx2(ResourceFormPrimitive,{label:"Update entity",fields,values:displayedValues(fields,values),disabled:!mutation.available,pending:mutation.pending,error:mutationMessage(mutation),...props.onCancel===undefined?{}:{onCancel:props.onCancel},onChange:(name,value)=>setDraft((current)=>({...current,values:{...current.values,[name]:wireValue(fields,name,value)}})),onSubmit:async()=>{const value=writableValues(fields,values);const result=await(mutation.status==="uncertain"?mutation.resubmit():mutation.submit({expectedRevision,value}));if(result.ok){props.onSuccess?.(result.value)}},renderControl:controlRenderer(props.entity,props.controls),submitLabel:mutation.status==="uncertain"?"Resubmit":"Save"})};var EntityForm2=(props)=>{const runtime=useEntityRuntime();if(runtime.state.status!=="authenticated"){return jsx2("output",{children:runtime.state.status})}return props.mode==="create"?jsx2(CreateEntityForm,{...props},runtime.formScope):jsx2(UpdateEntityForm,{...props,record:props.record},JSON.stringify([runtime.formScope,props.record.id]))};
2
- export{resourceKeys,ResourceQueryError2,unwrapResourceResult2,createResourceListQueryOptions,mapResourceAuthState2,hasResourceCapability2,clearProtectedResourceQueries,EntityRuntimeProvider,createDelegatedEntitySource,defineEntity2,useEntityUpdate2,useEntityCreate2,useEntityDelete2,useEntityList2,useEntityRecord2,useEntityViewState2,useMemoryEntityViewState2,EntityTable2,EntityList2,EntityForm2};