({ channel, children }: ProviderPropsType)
| 47 | * as a cell since we want to move away from that. |
| 48 | */ |
| 49 | export function PackageJsonProvider({ channel, children }: ProviderPropsType) { |
| 50 | const { cells, updateCell: updateCellOnClient, getOutput, clearOutput } = useCells(); |
| 51 | |
| 52 | const cell = cells.find((cell) => cell.type === 'package.json') as PackageJsonCellType; |
| 53 | |
| 54 | // outdated means package.json is out of date and needs to install deps. |
| 55 | // |
| 56 | // If outdated is an array, it means the specific entries in the array are |
| 57 | // packages that are not yet listed in package.json's dependencies. In this |
| 58 | // case, we must ensure we install these packages and save them to package.json. |
| 59 | // |
| 60 | // If outdated is true, it means there are packages in package.json that need |
| 61 | // to be installed. This can happen if user created or imported a srcbook and |
| 62 | // forgot to run `npm install` or when AI adds packages to package.json. |
| 63 | // |
| 64 | const [outdated, setOutdated] = useState<boolean | string[]>(false); |
| 65 | |
| 66 | const [validationError, setValidationError] = useState<string | null>(null); |
| 67 | |
| 68 | useEffectOnce(() => { |
| 69 | channel.push('deps:validate', {}); |
| 70 | }); |
| 71 | |
| 72 | const npmInstall = useCallback( |
| 73 | (packages?: string[]) => { |
| 74 | const error = getValidationError(cell.source); |
| 75 | setValidationError(error); |
| 76 | if (error === null) { |
| 77 | updateCellOnClient({ ...cell, status: 'running' }); |
| 78 | clearOutput(cell.id); |
| 79 | setOutdated(false); |
| 80 | channel.push('deps:install', { packages }); |
| 81 | } |
| 82 | }, |
| 83 | [cell, channel, updateCellOnClient, clearOutput], |
| 84 | ); |
| 85 | |
| 86 | useEffect(() => { |
| 87 | const callback = (response: DepsValidateResponsePayloadType) => { |
| 88 | // If we receive a response at all, it means there are outdated packages. |
| 89 | setOutdated(response.packages ?? true); |
| 90 | }; |
| 91 | |
| 92 | channel.on('deps:validate:response', callback); |
| 93 | return () => channel.off('deps:validate:response', callback); |
| 94 | }, [channel, npmInstall]); |
| 95 | |
| 96 | function updateCellOnServer(updates: PackageJsonCellUpdateAttrsType) { |
| 97 | channel.push('cell:update', { |
| 98 | cellId: cell.id, |
| 99 | updates, |
| 100 | }); |
| 101 | } |
| 102 | |
| 103 | function onChangeSource(source: string) { |
| 104 | const updates = { ...cell, source }; |
| 105 | updateCellOnClient(updates); |
| 106 |
nothing calls this directly
no test coverage detected